﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;

namespace EasyTrader.DataSet
{
    using BarDataCollection = List<EasyTrader.DataSet.BarDataItemList>;
    using BarDataList = List<EasyTrader.DataSet.BarDataItem>;
    using CodeList = List<CodeTable>;
    using CodePairList = List<EasyTrader.DataSet.CodePair>;
    using SimpleDataList = List<EasyTrader.DataSet.SimpleData>;


    public class DownloadCenter
    {
#region Realtime Object Buffer
        // 실시간 객체를 위한 버퍼 
        // 실시간으로 응답이 오면 데이터를 무조건 이 버퍼에 채워 넣기만 한다.
        // 이때 시간이 함께옴으로 시간으로 인덱스만 계산해 놓는다. 그러면 외부에서 타이머를 통해 정규적으로 인덱스를 참조하여 
        // 버퍼에 있는 데이터를 데이터 테이블에 저장한다.
        public object[] FutureCurOnlyTableBuffer = new object[GlobalVar.FutureCurOnlyTableColSize];
        public object[] FutureJpBidTableBuffer = new object[GlobalVar.FutureJpBidTableColSize];
        public object[] CPSvr8111STableBuffer = new object[GlobalVar.CPSvr8111STableColSize];
        public object[] CmeCurrTableBuffer = new object[GlobalVar.CmeCurrTableColSize];

        private bool FutureMstOpenSet = false;
        private bool CPSvrNew7221OpenSet = false;
        private bool CPSvr8111SOpenSet = false;

        private int CpSvr8111SIndex = -1;
        private int FutureCurOnlyIndex = -1;
        private int FutureJpBidIndex = -1;
        private int CmeCurrIndex = -1;
#endregion
#region Memer Variables

        private bool m_CmeCurrDataLock = false;
        private bool m_CPSvr8111SDataLock = false;
        private bool m_FutureCurOnlyLock = false;
        private bool m_FutureJpBidLock = false;

        private bool m_AllOptChartDataDownloaded = false;
        public bool AllOptChartDataDownloaded
        {
            get { return m_AllOptChartDataDownloaded; }
            set { m_AllOptChartDataDownloaded = value; }
        }


        private bool m_ATMChanged = false;
        public bool ATMChanged
        {
            get { return m_ATMChanged; }
            set { m_ATMChanged = value; }
        }


        private string m_CallATM = "";
        public string CallATM
        {
            get { return m_CallATM; }
            set { m_CallATM = value; }
        }
        private string m_PutATM = "";
        public string PutATM
        {
            get { return m_PutATM; }
            set { m_PutATM = value; }
        }
        private bool m_bReadCrossData = false;

        private EasyTrader.DataSet.BarDataTable m_BarTable = new EasyTrader.DataSet.BarDataTable("OptTable");
        CodePairList m_OptPastCodeList = new CodePairList();
        CodePairList m_OptChartCodeList = new CodePairList();
        public CodePairList OptChartCodeList
        {
            get { return m_OptChartCodeList; }
            set { m_OptChartCodeList = value; }
        }


        private int m_ChartCodeRange = GlobalVar.OptChartRange;
        

        private string[] m_ATMArray = null;
        public string[] ATMArray
        {
            get { return m_ATMArray; }
            set { m_ATMArray = value; }
        }
        private char m_OptChartUnit = 'm';
        public char OptChartUnit
        {
            get { return m_OptChartUnit; }
            set { m_OptChartUnit = value; }
        }

        private char m_OptChartMethod = '1';
        public char OptChartMethod
        {
            get { return m_OptChartMethod; }
            set { m_OptChartMethod = value; }
        }
        private short m_OptChartCycle = 1;
        public short OptChartCycle
        {
            get { return m_OptChartCycle; }
            set { m_OptChartCycle = value; }
        }
        private string[] arrOptExpDate = new string[100];
        private short m_FutChartCycle = 1;
        public short FutChartCycle
        {
            get { return m_FutChartCycle; }
            set { m_FutChartCycle = value; }
        }

        private short m_StockChartCycle = 1;
        private int m_StockChartIndex = 0;

        private object m_CurDay = 0;
        public object CurDay
        {
            get { return m_CurDay; }
            set { m_CurDay = value; }
        }
        private object m_PreDay = 0;
        public object PreDay
        {
            get { return m_PreDay; }
            set { m_PreDay = value; }
        }

        private object m_CurBaseDay = 0;
        public object CurBaseDay
        {
            get { return m_CurBaseDay; }
            set { m_CurBaseDay = value; }
        }

        private int m_ServerSec = 0;
        public int ServerSec
        {
            get { return m_ServerSec; }
            set { m_ServerSec = value; }
        }


        private bool m_Lock = false;
        public bool Lock
        {
            get { return m_Lock; }
            set { m_Lock = value; }
        }

        private EasyTrader.ETDataSet m_EasyTraderDataSet = null;
        public EasyTrader.ETDataSet EasyTraderDataSet
        {
            get { return m_EasyTraderDataSet; }
            set { m_EasyTraderDataSet = value; }
        }

        private System.Timers.Timer timer = new System.Timers.Timer();

        private CodeList m_CallPriceCodeList = new CodeList();

        // 콜코드와 풋 코드를 가격과 함께 모아 놓은 목록
        private CodeList m_CallPutCodeList = new CodeList();
        public CodeList CallPutCodeList
        {
            get { return m_CallPutCodeList; }
            set { m_CallPutCodeList = value; }
        }

        // 콜 코드만 모아 놓은 목록
        public CodeList CallPriceCodeList
        {
            get { return m_CallPriceCodeList; }
            set { m_CallPriceCodeList = value; }
        }

        
        // 풋 코드만 모아 놓은 목록
        private CodeList m_PutPriceCodeList = new CodeList();
        public CodeList PutPriceCodeList
        {
            get { return m_PutPriceCodeList; }
            set { m_PutPriceCodeList = value; }
        }
        // 콜과 풋의 상품 코드를 모아 놓은 목록
        private CodeList m_CenterPriceCodeList = new CodeList();
        public CodeList CenterPriceCodeList
        {
            get { return m_CenterPriceCodeList; }
            set { m_CenterPriceCodeList = value; }
        }

        // 선물 행사가만 가격순으로 모아놓은 목록
        private List<string> m_PriceCodeList = new List<string>();
        public List<string> PriceCodeList
        {
            get { return m_PriceCodeList; }
            set { m_PriceCodeList = value; }
        }

        // 차트에서 가져올 코드 목록만 모아놓은 리스트
        private string[] m_OptChartCodeArray = new string[6];
        public string[] OptChartCodeArray
        {
            get { return m_OptChartCodeArray; }
            set { m_OptChartCodeArray = value; }
        }
        

#endregion
#region Request Download Variables
        // 종목 코드 객체
        CPUTILLib.CpFutureCode m_CpFutureCode = new CPUTILLib.CpFutureCode();
        CPUTILLib.CpOptionCode m_CpOptionCode = new CPUTILLib.CpOptionCode();
        CPUTILLib.CpStockCode m_CpStockCode = new CPUTILLib.CpStockCode();
        CPUTILLib.CpCybosClass m_CpCybos = new CPUTILLib.CpCybosClass();

        // 옵션 현재 날짜 데이터를 가져오는 객체
        private CPSYSDIBLib.FutOptChartClass m_OptTodayFetcher = new CPSYSDIBLib.FutOptChartClass();
        private int m_OptTodayTryCount = 0;
        public int OptTodayTryCount
        {
            get { return m_OptTodayTryCount; }
            set { m_OptTodayTryCount = value; }
        }
        // 옵션 날짜별 데이터를 가져오는 객체
        private CPSYSDIBLib.FutOptChartClass m_OptDayFetcher = new CPSYSDIBLib.FutOptChartClass();
        private int m_OptDayTryCount = 0;

        // 선물 옵션 차트 데이터를 가져오는 객체
        private CPSYSDIBLib.FutOptChartClass m_OptChartFetcher = new CPSYSDIBLib.FutOptChartClass();
        private int m_OptChartTryCount = 0;

        // 선물 날짜별 데이터를 가져오는 객체
        private CPSYSDIBLib.FutOptChartClass m_FutDayFetcher = new CPSYSDIBLib.FutOptChartClass();
        private int m_FutDayTryCount = 0;

        // 옵션 등가 목록을 가져오는 객체 
        private DSCBO1Lib.OptionAtm m_OptionAtmFetcher = new DSCBO1Lib.OptionAtm();
        private int m_OptionAtmTryCount = 1;

        // 원달러 환율가져오는 객체
        private DSCBO1Lib.CpFore8312Class m_CpFore8312Fetcher = new DSCBO1Lib.CpFore8312Class();
        private int m_CpFore8312TryCount = 0;

        // 야간 선물 매수, 매도 호가 건수 수집 객체
        private CPSYSDIBLib.CmeMstClass m_CmeMstFetcher = new CPSYSDIBLib.CmeMstClass();
        private int m_CmeMstTryCount = 0;

        // 주간 선물 차트 데이터를 가져오는 객체
        private CPSYSDIBLib.FutOptChartClass m_FutChartFetcher = new CPSYSDIBLib.FutOptChartClass();
        private int m_FutChartTryCount = 0;

        // 주간 주식 차트 데이터를 가져오는 객체
        private CPSYSDIBLib.StockChartClass m_StockChartFetcher = new CPSYSDIBLib.StockChartClass();
        private int m_StockChartTryCount = 0;

        // 요청 매도, 매수 총호가 수량, 매도, 매수 총 호가 건수
        private DSCBO1Lib.FutureMstClass m_FutureMstFetcher = new DSCBO1Lib.FutureMstClass();
        private int m_FutureMstTryCount = 0;

        // 요청 주체별 거래량 수집 객체
        private CPSYSDIBLib.CpSvrNew7221Class m_CpSvrNew7221Fetcher = new CPSYSDIBLib.CpSvrNew7221Class();
        private int m_CpSvrNew7221TryCount = 0;

        // 해외지수 데이터를 가져오는 객체
        private DSCBO1Lib.CpSvr8300Class m_CpSvr8300Fetcher = new DSCBO1Lib.CpSvr8300Class();
        private int m_CpSvr8300TryCount = 0;

        // 야간선물 일간 데이터를 가져오는 객체
        private CPSYSDIBLib.CmeDailyClass m_CmeDailyFetcher = new CPSYSDIBLib.CmeDailyClass();
        private int m_CmeDailyTryCount = 0;

        // 선물 옵션 차트 데이터를 가져오는 객체
        private CPSYSDIBLib.FutOptChartClass m_OptPastChartFetcher = new CPSYSDIBLib.FutOptChartClass();
        private int m_OptPastChartTryCount = 0;

#endregion
#region Realtime Downloader Variables

        // 실시간 선물 호가 수집 객체
        private CPSYSDIBLib.FutureJpBidClass m_FutureJpBid = new CPSYSDIBLib.FutureJpBidClass();
        // 실시간 선물 현재가 수집 객체
        private DSCBO1Lib.FutureCurOnlyClass m_FutureCurOnly = new DSCBO1Lib.FutureCurOnlyClass();
        // 실시간 프로그램 거래량 수집 객체
        private DSCBO1Lib.CpSvr8111SClass m_CpSvr8111S = new DSCBO1Lib.CpSvr8111SClass();
        // 실시간 야간선물 현재가 수집 객체
        private CPSYSDIBLib.CmeCurrClass m_CmeCur = new CPSYSDIBLib.CmeCurrClass();
        // 실시간 세계 시장 정보를 가져오는 객체
        CPSYSDIBLib.WorldCurClass m_WorldCur = new CPSYSDIBLib.WorldCurClass();

#endregion
#region Member Functions

        public string GetFutureCode()
        {
            object code = m_CpFutureCode.GetData(0, 0);

            return code.ToString();
        }
        // 이 함수는 실시간으로 값을 확인하여 등가 코드를 바꾼다.
        public void CalcATM()
        {
            if (m_ATMChanged == true)
                return;

            string callATM = GetCallAtm();
            string putATM = GetPutAtm();
            if (callATM != "" && putATM != "")
            {
                if (callATM != m_CallATM && putATM != m_PutATM)
                {
                    GlobalVar.CATM = m_CallATM = callATM;
                    GlobalVar.PATM = m_PutATM = putATM;

                    // 옵션 차트 코드 목록을 다시 만든다.
                    MakeOptChartCodeList(callATM, putATM);
                    // 옵션 차트 코드 테이블 이름을 다시 바꿔 준다.
                    m_EasyTraderDataSet.ClearOptTables();

                    // 옵션 시스템의 상태 업데이트를 금지한다.
                    m_AllOptChartDataDownloaded = false;
                    // 옵션 차트 데이터 다운로드 시도 개수를 0으로 해준다.
                    // 왜냐하면 데이터를 다운로드해야 하는 정보가 바뀠기 때문이다.
                    m_OptChartTryCount = 0;

                    m_ATMChanged = true;
                }
                else
                    m_ATMChanged = true;
            }
            else
                SetAtm();

        }


        // 옵션의 날짜별 행사가별 코드 목록을 만든다.
        // 데이터가 없는 것들만 골라서 가져온다.
        private void MakeOptPastCodeList()
        {
            m_OptPastCodeList.Clear();

            for (int i = 0; i < m_EasyTraderDataSet.FutDayList.Count; i++)
            {
                EasyTrader.DataSet.BarDataItem item = m_EasyTraderDataSet.FutDayList[i];
                for (int j = 0; j < CenterPriceCodeList.Count; j++)
                {
                    EasyTrader.DataSet.CodeTable priceCode = CenterPriceCodeList[j];
                    EasyTrader.DataSet.CodePair pair = new EasyTrader.DataSet.CodePair();
                    pair.Date = item.Date;
                    pair.Code = priceCode.Code;
                    if (m_BarTable.IsDataFileExist(pair.Date, pair.Code) == false)
                    {
                        m_OptPastCodeList.Add(pair);
                    }
                }
            }
        }

        // 가져올 차트 데이터 목록을 만든다.
        // 등가를 중심으로 정해진 범위의 것만 가져온다.
        public void MakeOptChartCodeList()
        {
            m_OptChartCodeList.Clear();

            // 콜 코드를 먼저 만들어 준다.
            string callATM = GetCallAtm(m_CurDay);
            int atmRow = 0;
            if (callATM != "")
            {
                for (int i = 0; i < CallPriceCodeList.Count; i++)
                {
                    EasyTrader.DataSet.CodeTable code = CallPriceCodeList[i];
                    if (callATM == code.Code)
                    {
                        atmRow = i;
                        break;
                    }
                }
                int start = atmRow - m_ChartCodeRange;
                int end = atmRow + m_ChartCodeRange;
                for (int i = start; i <= end; i++)
                {
                    EasyTrader.DataSet.CodeTable code = CallPriceCodeList[i];
                    EasyTrader.DataSet.CodePair pair = new EasyTrader.DataSet.CodePair();
                    pair.Date = m_CurDay;
                    pair.Code = code.Code;
                    m_OptChartCodeList.Add(pair);
                }
            }

            // 풋 코드는 항상 뒤에 만들어 준다. 
            string putATM = GetPutAtm(m_CurDay);
            if (putATM != "")
            {
                for (int i = 0; i < PutPriceCodeList.Count; i++)
                {
                    EasyTrader.DataSet.CodeTable code = PutPriceCodeList[i];
                    if (putATM == code.Code)
                    {
                        atmRow = i;
                        break;
                    }
                }
                int start = atmRow - m_ChartCodeRange;
                int end = atmRow + m_ChartCodeRange;
                for (int i = start; i <= end; i++)
                {
                    EasyTrader.DataSet.CodeTable code = PutPriceCodeList[i];
                    EasyTrader.DataSet.CodePair pair = new EasyTrader.DataSet.CodePair();
                    pair.Date = m_CurDay;
                    pair.Code = code.Code;
                    m_OptChartCodeList.Add(pair);
                }
            }
            //m_EasyTraderDataSet.MakeOptPastCodeList(m_OptChartCodeList, Convert.ToInt32(m_CurDay));
        }

        // 가져올 차트 데이터 목록을 만든다.
        // 등가를 중심으로 정해진 범위의 것만 가져온다.
        public void MakeOptChartCodeList(string a_CallATM, string a_PutATM)
        {
            if (a_CallATM == "" || a_PutATM == "")
                return;

            m_OptChartCodeList.Clear();

            // 콜 코드를 먼저 만들어 준다.
            int atmRow = 0;
            if (a_CallATM != "")
            {
                for (int i = 0; i < CallPriceCodeList.Count; i++)
                {
                    EasyTrader.DataSet.CodeTable code = CallPriceCodeList[i];
                    if (a_CallATM == code.Code)
                    {
                        atmRow = i;
                        break;
                    }
                }
                int start = atmRow - m_ChartCodeRange;
                int end = atmRow + m_ChartCodeRange;
                for (int i = start; i <= end; i++)
                {
                    EasyTrader.DataSet.CodeTable code = CallPriceCodeList[i];
                    EasyTrader.DataSet.CodePair pair = new EasyTrader.DataSet.CodePair();
                    pair.Date = m_CurDay;
                    pair.Code = code.Code;
                    m_OptChartCodeList.Add(pair);
                }
            }

            // 풋 코드는 항상 뒤에 만들어 준다. 
            if (a_PutATM != "")
            {
                for (int i = 0; i < PutPriceCodeList.Count; i++)
                {
                    EasyTrader.DataSet.CodeTable code = PutPriceCodeList[i];
                    if (a_PutATM == code.Code)
                    {
                        atmRow = i;
                        break;
                    }
                }
                int start = atmRow - m_ChartCodeRange;
                int end = atmRow + m_ChartCodeRange;
                for (int i = start; i <= end; i++)
                {
                    EasyTrader.DataSet.CodeTable code = PutPriceCodeList[i];
                    EasyTrader.DataSet.CodePair pair = new EasyTrader.DataSet.CodePair();
                    pair.Date = m_CurDay;
                    pair.Code = code.Code;
                    m_OptChartCodeList.Add(pair);
                }
            }
        }

        private void PutRealTimeData()
        {
            PutCmeCurrData();
            PutCPSvr8111SData();
            PutFutureCurOnlyData();
            PutFutureJpBidData();
        }

        public int GetOpenedDays(int a_StartDay, int a_EndDay)
        {

            int dayCount = 0;
            for (int i = 0; i < m_EasyTraderDataSet.FutDayList.Count; i++)
            {
                EasyTrader.DataSet.BarDataItem item = m_EasyTraderDataSet.FutDayList[i];
                int curDay = Convert.ToInt32(item.Date.ToString());
                if (curDay > a_StartDay)
                    continue;
                if (curDay < a_EndDay)
                    break;
                dayCount++;
                //Console.WriteLine(curDay.ToString());
                //Console.WriteLine(dayCount.ToString());
            }

            return dayCount;
        }

        public void SetDay(object a_CurDay)
        {
            int openDay, preOpenDay;
            int today = Convert.ToInt32(a_CurDay);
            if (today == 0)
                today = GlobalVar.DateToInt();
            FindLastOpenDay(today, out openDay, out preOpenDay);

            m_CurDay = openDay;
            m_PreDay = preOpenDay;
            //m_CurMonth = m_CurDay.ToString().Substring(m_CurDay.ToString().Length - 4, 2);

            int exDay = FindRecentExpDay(m_CurDay);
            m_CurBaseDay = exDay + 1;

            //DDEForm.WorkDate = Convert.ToInt32(m_CurDay);

            //DDEForm.SetDay(m_CurDay, m_PreDay);
        }

        public int GetElapDays()
        {
            int dayCount = 0;
            int exDay = FindRecentExpDay(m_CurDay);
            int baseDay = exDay + 1;
            for (int i = 0; i < m_EasyTraderDataSet.FutDayList.Count; i++)
            {
                BarDataItem item = m_EasyTraderDataSet.FutDayList[i];
                int curDay = Convert.ToInt32(item.Date.ToString());
                if (curDay < baseDay)
                    break;
                dayCount++;
                //Console.WriteLine(curDay.ToString());
                //Console.WriteLine(dayCount.ToString());
            }

            return dayCount;
        }

        private void ResetDownloadCount()
        {
            if (m_CpSvrNew7221TryCount >= 1)
            {
                //Console.WriteLine("ResetDownloadCount");
                DateTime now = DateTime.Now;
                //Console.WriteLine(now.Second.ToString() + now.Millisecond.ToString());

                if (GlobalVar.CmeDailyRefCount > 0)
                    m_CmeDailyTryCount = 0;
                else
                    m_CmeDailyTryCount = 1;
                if (GlobalVar.CmeMstRefCount > 0)
                    m_CmeMstTryCount = 0;
                else
                    m_CmeMstTryCount = 1;
                if (GlobalVar.CpFore8312RefCount > 0)
                    m_CpFore8312TryCount = 0;
                else
                    m_CpFore8312TryCount = GlobalVar.m_MoneyExCodeTable.Length;

                if (GlobalVar.CpSvr8300RefCount > 0)
                    m_CpSvr8300TryCount = 0;
                else
                    m_CpSvr8300TryCount = GlobalVar.m_WorldCodeTable.Length;

                if (GlobalVar.OpChartRefCount > 0)
                    m_OptChartTryCount = 0;
                else
                    m_OptChartTryCount = m_OptChartCodeArray.Length;
                if (GlobalVar.StockChartRefCount > 0)
                    m_StockChartTryCount = 0;
                else
                    m_StockChartTryCount = 1;
                if (GlobalVar.OpTodayRefCount > 0)
                    m_OptTodayTryCount = 0;
                else
                    m_OptTodayTryCount = m_CenterPriceCodeList.Count;

                m_OptionAtmTryCount = 1;
                m_FutChartTryCount = 0;
                m_FutureMstTryCount = 0;
                m_CpSvrNew7221TryCount = 0;

                m_Lock = false;

                GlobalVar.StateMessage = "데이터 수신을 완료했습니다.";

                ReadCrossDay();

                // 여기서 dde 데이터를 만들어 준다.
                m_EasyTraderDataSet.CreateDDEData();

                GlobalVar.AllDataDownloaded = true;
            }
        }

        public int FindOptChartCodeIndex(string a_OpCode)
        {
            int row = -1;
            for (int i = 0; i < m_OptChartCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodePair code = m_OptChartCodeList[i];
                if (code.Code.ToString() == a_OpCode)
                {
                    row = i;
                    break;
                }
            }

            return row;
        }

        // 가장 최근 영업일을 찾는다.
        private void FindLastOpenDay(int a_CurDate, out int a_OpenDay, out int a_PreOpenDay)
        {
            a_OpenDay = 0;
            a_PreOpenDay = 0;
            for (int i = 0; i < m_EasyTraderDataSet.FutDayList.Count; i++)
            {
                BarDataItem item = m_EasyTraderDataSet.FutDayList[i];
                int curDate = Convert.ToInt32(item.Date);
                if (curDate <= a_CurDate)
                {
                    a_OpenDay = curDate;
                    item = m_EasyTraderDataSet.FutDayList[i + 1];
                    a_PreOpenDay = Convert.ToInt32(item.Date);
                    break;
                }
            }
        }

        public int FindNextOpenDay(int a_CurDate)
        {
            int a_OpenDay = 0;
            for (int i = 0; i < m_EasyTraderDataSet.FutDayList.Count; i++)
            {
                BarDataItem item = m_EasyTraderDataSet.FutDayList[i];
                int curDate = Convert.ToInt32(item.Date);
                if (curDate <= a_CurDate)
                {
                    // 최신날짜 부터 있으므로 인덱스를 감소시키면 다음 일이 나온다.
                    int index = i - 1;
                    if (index < 0)
                        index = 0;
                    item = m_EasyTraderDataSet.FutDayList[index];
                    a_OpenDay = Convert.ToInt32(item.Date);
                    break;
                }
            }

            return a_OpenDay;
        }

        // 가장 최근 영업일을 찾는다.
        public int FindPreOpenDay(int a_CurDate)
        {
            int a_OpenDay = 0;
            for (int i = 0; i < m_EasyTraderDataSet.FutDayList.Count; i++)
            {
                BarDataItem item = m_EasyTraderDataSet.FutDayList[i];
                int curDate = Convert.ToInt32(item.Date);
                if (curDate <= a_CurDate)
                {
                    // 최신날짜 부터 있으므로 인덱스를 증가시키면 과거 일이 나온다.
                    int index = i + 1;
                    if (index > m_EasyTraderDataSet.FutDayList.Count - 1)
                        index = m_EasyTraderDataSet.FutDayList.Count - 1;
                    item = m_EasyTraderDataSet.FutDayList[index];
                    a_OpenDay = Convert.ToInt32(item.Date);
                    break;
                }
            }

            return a_OpenDay;
        }

        public int FindLastOpenDay(int a_CurDate)
        {
            int a_OpenDay = 0;
            for (int i = 0; i < m_EasyTraderDataSet.FutDayList.Count; i++)
            {
                BarDataItem item = m_EasyTraderDataSet.FutDayList[i];
                int curDate = Convert.ToInt32(item.Date);
                if (curDate <= a_CurDate)
                {
                    a_OpenDay = curDate;
                    break;
                }
            }

            return a_OpenDay;
        }

        // 가장 최근 만기일을 찾는다.
        public int FindRecentExpDay(object a_CurDay)
        {
            int curDate = Convert.ToInt32(a_CurDay);
            int rExDay = 0;
            for (int i = 99; i > 0; i--)
            {
                int curExDate = Convert.ToInt32(arrOptExpDate[i]);
                if (curExDate != 0 && curExDate < curDate)
                {
                    rExDay = curExDate;
                    break;
                }
            }

            return rExDay;
        }

        // 만기일 목록을 읽어 들인다.
        private void ReadOpExpDate()
        {
            string fileName = Directory.GetCurrentDirectory();
            fileName += "\\OpExpDate.txt";
            if (File.Exists(fileName))
            {
                using (StreamReader sr = new StreamReader(fileName))
                {
                    int i = 0;
                    while (sr.Peek() >= 0)
                    {
                        string opExDate = sr.ReadLine();
                        arrOptExpDate[i] = opExDate;
                        i++;
                    }
                }
            }
        }

        public void ReadOpCross()
        {
            /*
            string fileName = Directory.GetCurrentDirectory();
            fileName += "\\OpCross.txt";
            if (File.Exists(fileName))
            {
                using (StreamReader sr = new StreamReader(fileName))
                {
                    int i = 0;
                    int oldDate = 0;
                    EasyTrader.DataSet.DayCrossData newDayData = null;
                    while (sr.Peek() >= 0)
                    {
                        string opCrossData = sr.ReadLine();
                        string[] words = opCrossData.Split(',');

                        int curDate = Convert.ToInt32(words[0]);
                        string curCode =words[1];
                        int curType = Convert.ToInt32(words[2]);
                        double curVal = Convert.ToDouble(words[3]);
                        string curCenterVal = words[4];

                        string priceCode = curCode.Substring(curCode.Length - 3, 3);
                        string sideCode = curCode.Substring(0, 1);

                        if (curDate != oldDate)
                        {
                            newDayData = new EasyTrader.DataSet.DayCrossData();
                            newDayData.Date = curDate;
                            m_EasyTraderDataSet.OptCrossMonthData.Add(newDayData);
                        }
                        SimpleDataList dataList = newDayData.DataList;
                        EasyTrader.DataSet.SimpleData foundData = m_EasyTraderDataSet.FindOptCrossData(newDayData, priceCode);
                        i++;
                        if (foundData != null)
                        {
                            if (sideCode == "2")
                            {
                                foundData.CallCode = curCode;
                                foundData.CallType = curType;
                                foundData.CallVal = curVal;
                            }
                            else if (sideCode == "3")
                            {
                                foundData.PutCode = curCode;
                                foundData.PutType = curType;
                                foundData.PutVal = curVal;
                            }
                        }
                        else
                        {
                            EasyTrader.DataSet.SimpleData curData = new EasyTrader.DataSet.SimpleData();
                            curData.Date = curDate;
                            curData.PriceCode = priceCode;
                            curData.CenterVal = curCenterVal;
                            if (sideCode == "2")
                            {
                                curData.CallCode = curCode;
                                curData.CallType = curType;
                                curData.CallVal = curVal;
                            }
                            else if (sideCode == "3")
                            {
                                curData.PutCode = curCode;
                                curData.PutType = curType;
                                curData.PutVal = curVal;
                            }
                            dataList.Add(curData);
                        }

                        oldDate = curDate;
                    }
                }
            }*/
        }

        public void ReadCrossDay()
        {
            if (m_bReadCrossData == true)
                return;

            // 일단 기존의 데이터를 지워준다.
            m_EasyTraderDataSet.OptCrossMonthData.Clear();
            string fileName = Directory.GetCurrentDirectory();
            fileName += "\\CrossDay.txt";
            if (File.Exists(fileName))
            {
                using (StreamReader sr = new StreamReader(fileName))
                {
                    EasyTrader.DataSet.DayCrossData newDayData = null;
                    //string atm = GetCallAtm(m_CurDay);
                    //string centerCode = atm.Substring(atm.Length - 3, 3);

                    while (sr.Peek() >= 0)
                    {
                        string opCrossData = sr.ReadLine();
                        string[] words = opCrossData.Split(',');
                        string date = words[0];
                        string CallPutCode = words[1];
                        string centerCode = words[2];

                        newDayData = new EasyTrader.DataSet.DayCrossData();
                        newDayData.Date = Convert.ToInt32(date);
                        m_EasyTraderDataSet.OptCrossMonthData.Add(newDayData);
                        EasyTrader.DataSet.SimpleData foundData = null;
                        for (int i = 0; i < EasyTraderDataSet.OptDayDataList.Count; i++)
                        {
                            // 행사가별 일별 시고저종 모아 놓은 목록
                            EasyTrader.DataSet.BarDataItemList data = EasyTraderDataSet.OptDayDataList[i];
                            string code = data.Code.ToString();
                            string sideCode = code.Substring(0, 1);
                            string priceCode = code.Substring(code.Length - 3, 3);

                            // 한 행사가에 대한 일별 시고저종 목록
                            List<BarDataItem> dataList = data.DataList;
                            for (int j = 0; j < dataList.Count; j++)
                            {
                                BarDataItem item = dataList[j];
                                if (item.Date.ToString() == date)
                                {
                                    // 콜 뒤집기 였을 경우
                                    if (CallPutCode == "C")
                                    {
                                        foundData = m_EasyTraderDataSet.FindOptCrossData(newDayData, priceCode);
                                        if (foundData == null)
                                        {
                                            foundData = new EasyTrader.DataSet.SimpleData();
                                            foundData.Date = Convert.ToInt32(date);
                                            foundData.CenterVal = centerCode;
                                            foundData.PriceCode = priceCode;
                                            newDayData.DataList.Add(foundData);
                                        }
                                        // 이날 콜의 저가가 마디가 풋의 고가가 목표가
                                        if (sideCode == "2")
                                        {
                                            foundData.CallCode = code;
                                            foundData.CallType = 0;
                                            foundData.CallVal = Convert.ToDouble(item.Low.ToString());
                                        }
                                        else if (sideCode == "3")
                                        {
                                            foundData.PutCode = code;
                                            foundData.PutType = 1;
                                            foundData.PutVal = Convert.ToDouble(item.High.ToString());
                                        }
                                    }
                                    else if (CallPutCode == "P") // 풋 뒤집기 였을 경우
                                    {
                                        foundData = m_EasyTraderDataSet.FindOptCrossData(newDayData, priceCode);
                                        if (foundData == null)
                                        {
                                            foundData = new EasyTrader.DataSet.SimpleData();
                                            foundData.Date = Convert.ToInt32(date);
                                            foundData.CenterVal = centerCode;
                                            foundData.PriceCode = priceCode;
                                            newDayData.DataList.Add(foundData);
                                        }
                                        // 이날 풋의 저가가 마디가 콜의 고가가 목표가
                                        if (sideCode == "2")
                                        {
                                            foundData.CallCode = code;
                                            foundData.CallType = 1;
                                            foundData.CallVal = Convert.ToDouble(item.High.ToString());
                                        }
                                        else if (sideCode == "3")
                                        {
                                            foundData.PutCode = code;
                                            foundData.PutType = 0;
                                            foundData.PutVal = Convert.ToDouble(item.Low.ToString());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            m_bReadCrossData = true;
        }


        private void MakeOpCodeList()
        {
            GetCallPriceCodeList();
            GetPutPriceCodeList();
            GetPriceCodeList();
            MakeCenterPriceCodeList();
            MakeCallPutCodeList();

        }

        private void GetCallPriceCodeList()
        {
            int codeCount = m_CpOptionCode.GetCount();
            string[] arrOpCode = new string[codeCount];
            for (short i = 0; i < codeCount; i++)
            {
                arrOpCode[i] = m_CpOptionCode.GetData(0, i).ToString();
            }

            string oCode = arrOpCode[0];
            string oldMonthCode = oCode.Substring(oCode.Length - 4, 1);
            for (short i = 0; i < codeCount; i++)
            {
                oCode = arrOpCode[i];
                string monthCode = oCode.Substring(oCode.Length - 4, 1);
                string sideCode = oCode.Substring(0, 1);
                if (sideCode != "2")
                    continue;
                if (oldMonthCode == monthCode)
                {
                    CodeTable newCode = new CodeTable();
                    newCode.Code = oCode;
                    m_CallPriceCodeList.Add(newCode);
                }
                else
                    break;
            }
        }

        private void GetPriceCodeList()
        {
            int codeCount = m_CpOptionCode.GetCount();
            string[] arrOpCode = new string[codeCount];
            for (short i = 0; i < codeCount; i++)
            {
                arrOpCode[i] = m_CpOptionCode.GetData(0, i).ToString();
            }

            string oCode = arrOpCode[0];
            string oldMonthCode = oCode.Substring(oCode.Length - 4, 1);
            for (short i = 0; i < codeCount; i++)
            {
                oCode = arrOpCode[i];
                string monthCode = oCode.Substring(oCode.Length - 4, 1);
                if (oldMonthCode == monthCode)
                {
                    string priceCode = oCode.Substring(oCode.Length - 3, 3);
                    m_PriceCodeList.Add(priceCode);
                }
                else
                    break;
            }
        }

        // 행사가가 작은 것부터 차례대로 읽어 온다.
        private void GetPutPriceCodeList()
        {
            int codeCount = m_CpOptionCode.GetCount();
            string[] arrOpCode = new string[codeCount];
            for (short i = 0; i < codeCount; i++)
            {
                arrOpCode[i] = m_CpOptionCode.GetData(0, i).ToString();
            }

            string oCode = arrOpCode[0];
            string oldMonthCode = oCode.Substring(oCode.Length - 4, 1);
            for (short i = 0; i < codeCount; i++)
            {
                oCode = arrOpCode[i];
                string monthCode = oCode.Substring(oCode.Length - 4, 1);
                string sideCode = oCode.Substring(0, 1);
                if (sideCode != "3")
                    continue;
                if (oldMonthCode == monthCode)
                {
                    CodeTable newCode = new CodeTable();
                    newCode.Code = oCode;
                    m_PutPriceCodeList.Add(newCode);
                }
                else
                    break;
            }
        }

        private void MakeCenterPriceCodeList()
        {
            if (m_CallPriceCodeList.Count == 0 || m_PutPriceCodeList.Count == 0)
                return;
            for (int i = 0; i < m_CallPriceCodeList.Count; i++)
            {
                string callCode = m_CallPriceCodeList[m_CallPriceCodeList.Count - i - 1].Code;
                string putCode = m_PutPriceCodeList[m_PutPriceCodeList.Count - i - 1].Code;
                EasyTrader.DataSet.CodeTable newCode = new EasyTrader.DataSet.CodeTable();
                newCode.CallCode = callCode;
                newCode.CellRowNum = i;
                newCode.Code = callCode;
                m_CenterPriceCodeList.Add(newCode);
                newCode = new EasyTrader.DataSet.CodeTable();
                newCode.PutCode = putCode;
                newCode.CellRowNum = i;
                newCode.Code = putCode;
                m_CenterPriceCodeList.Add(newCode);
            }
        }

        private void MakeCallPutCodeList()
        {
            if (m_CallPriceCodeList.Count == 0 || m_PutPriceCodeList.Count == 0)
                return;
            for (int i = 0; i < m_CallPriceCodeList.Count; i++)
            {
                string callCode = m_CallPriceCodeList[m_CallPriceCodeList.Count - i - 1].Code;
                string putCode = m_PutPriceCodeList[m_PutPriceCodeList.Count - i - 1].Code;
                string priceCode = callCode.Substring(callCode.Length - 3, 3);
                EasyTrader.DataSet.CodeTable newCode = new EasyTrader.DataSet.CodeTable();
                newCode.CellRowNum = i;
                newCode.CallCode = callCode;
                newCode.PutCode = putCode;
                newCode.Code = priceCode;
                m_CallPutCodeList.Add(newCode);
            }
        }

        public EasyTrader.DataSet.CodeTable FindCallPutCodeList(string a_PriceCode)
        {
            for (int i = 0; i < m_CallPutCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodeTable code = m_CallPutCodeList[i];
                if (code.Code == a_PriceCode)
                    return code;
            }

            return null;
        }

        // 서버 실시간 데이터 객체들을 초기화 합니다.
        private void InitRealTimeDataObject()
        {
            string futureCode = m_CpFutureCode.GetData(0, 0).ToString();

            m_FutureJpBid.SetInputValue(0, futureCode);
            m_FutureJpBid.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_FutureJpBid);
            m_FutureJpBid.Subscribe();

            m_FutureCurOnly.SetInputValue(0, futureCode);
            m_FutureCurOnly.Received += new DSCBO1Lib._IDibEvents_ReceivedEventHandler(OnReceived_FutureCurOnly);
            m_FutureCurOnly.Subscribe();

            m_CpSvr8111S.Received += new DSCBO1Lib._IDibEvents_ReceivedEventHandler(OnReceived_CpSvr8111S);
            m_CpSvr8111S.Subscribe();

            m_CmeCur.SetInputValue(0, futureCode);
            m_CmeCur.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_CmeCurr);
            m_CmeCur.Subscribe();
        }

        private void InitRequestDataObject()
        {
            m_CpSvr8300Fetcher.Received += new DSCBO1Lib._IDibEvents_ReceivedEventHandler(OnReceived_CpSvr8300);
            m_CpFore8312Fetcher.Received += new DSCBO1Lib._IDibEvents_ReceivedEventHandler(OnReceived_Cp8312);
            m_CmeDailyFetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_CmeDaily);
            m_FutChartFetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_FutChart);
            m_FutureMstFetcher.Received += new DSCBO1Lib._IDibEvents_ReceivedEventHandler(OnReceived_FutureMst);
            m_CpSvrNew7221Fetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_CpSvrNew7221);
            m_StockChartFetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_StockChart);
            m_CmeMstFetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_CmeMst);


            m_OptTodayFetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_OptToday);
            m_OptChartFetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_OptChart);
            m_OptDayFetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_OptDay);
            m_FutDayFetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_FutDay);
            m_OptionAtmFetcher.Received += new DSCBO1Lib._IDibEvents_ReceivedEventHandler(OnReceived_OptionATM);
            m_OptPastChartFetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived_OptPastChart);
        }

        private void InitTimer()
        {
            timer.Interval = 100;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerTick);
            //timer.Start();
        }

        public void ResetSimulDataTryCount()
        {
            m_EasyTraderDataSet.FutDayList.Clear();
            m_EasyTraderDataSet.OptDayDataList.Clear();
            m_FutDayTryCount = 0;
            m_OptDayTryCount = 0;
            m_FutChartTryCount = 0;
            m_OptChartTryCount = 0;
        }

        private void OnTimerTick(object sender, EventArgs e)
        {
            int rCount = GetRequestRemainCount();
            if (rCount <= 0)
                return;
            if (m_Lock == true)
                return;

            if (GlobalVar.OperationMode == GlobalVar.OperationModeSimul)
            {
                if (GlobalVar.AllDataDownloaded == true)
                    return;

                // 1회용 데이터들
                if (m_FutDayTryCount < 1)
                    DownLoadFutDay();
                if (m_FutDayTryCount >= 1 && m_OptDayTryCount < m_CenterPriceCodeList.Count)
                    DownLoadOptDay();
                
                if (m_OptDayTryCount >= m_CenterPriceCodeList.Count && m_FutChartTryCount < 1)
                {
                    // 옵션 마디가와 목표가를 읽어들여 설정해 준다.
                    ReadCrossDay();
                    DownloadFutChart();
                }

                if (m_FutChartTryCount >= 1 && m_OptChartTryCount < m_OptChartCodeList.Count)
                {
                    CalcATM();
                    DownLoadOptChart();
                }

                if (m_OptChartCodeList.Count > 0 && m_OptChartTryCount >= m_OptChartCodeList.Count)
                {
                    m_EasyTraderDataSet.CreateDDEData();
                    GlobalVar.AllDataDownloaded = true;
                    GlobalVar.StateMessage = "데이터 수신을 완료했습니다.";
                    timer.Stop();
                }
            }
            else
            {
                if (GlobalVar.AllDataDownloaded == true)
                    CalcATM();
                //DateTime now = DateTime.Now;
                //Console.WriteLine(now.Second.ToString() + now.Millisecond.ToString());

                // 1회용 데이터들
                if (m_FutDayTryCount < 1)
                    DownLoadFutDay();
                if (m_FutDayTryCount >= 1 && m_OptDayTryCount < m_CenterPriceCodeList.Count)
                    DownLoadOptDay();
                //if (m_OptDayTryCount >= m_CenterPriceCodeList.Count && m_OptPastChartTryCount < m_OptPastCodeList.Count)
                //    DownLoadOptPastChart();

                int activeNumber = 0;

                // 참조하는 것들이 있을 때만 데이터를 요청한다.
                if (GlobalVar.CmeDailyRefCount > 0)
                {
                    activeNumber = 1;
                    if (m_OptDayTryCount >= m_CenterPriceCodeList.Count && m_CmeDailyTryCount < 1)
                        DownloadCmeDaily();
                }
                else
                    m_CmeDailyTryCount = 1;

                if (GlobalVar.CmeMstRefCount > 0)
                {
                    activeNumber = 2;
                    if (m_CmeDailyTryCount >= 1 && m_CmeMstTryCount < 1)
                        DownLoadCmeMst();
                }
                else
                    m_CmeMstTryCount = 1;

                if (GlobalVar.CpFore8312RefCount > 0)
                {
                    activeNumber = 3;
                    if (m_CmeMstTryCount >= 1 && m_CpFore8312TryCount < GlobalVar.m_MoneyExCodeTable.Length)
                        DownloadCpFore8312();
                }
                else
                    m_CpFore8312TryCount = GlobalVar.m_MoneyExCodeTable.Length;

                if (GlobalVar.CpSvr8300RefCount > 0)
                {
                    activeNumber = 4;
                    if (m_CpSvr8300TryCount < GlobalVar.m_WorldCodeTable.Length)
                        DownloadCpSvr8300();
                }
                else
                    m_CpSvr8300TryCount = GlobalVar.m_WorldCodeTable.Length;

                if (GlobalVar.OpChartRefCount > 0)
                {
                    activeNumber = 5;
                    if (m_OptChartTryCount < m_OptChartCodeList.Count)
                        DownLoadOptChart();
                }
                else
                    m_OptChartTryCount = m_OptChartCodeList.Count;

                if (GlobalVar.StockChartRefCount > 0)
                {
                    activeNumber = 6;
                    if (m_StockChartTryCount < 1)
                        DownloadStockChart();
                }
                else
                    m_StockChartTryCount = 1;
                if (GlobalVar.OpTodayRefCount > 0)
                {
                    activeNumber = 7;
                    if (m_StockChartTryCount >= 1 && m_OptTodayTryCount < m_OptChartCodeList.Count)
                        DownLoadOptToday();
                }
                else
                    m_OptTodayTryCount = m_OptChartCodeList.Count;

                // 매번 받아야 하는 데이터들
                if (m_OptDayTryCount >= m_CenterPriceCodeList.Count && m_OptionAtmTryCount < 1)
                {
                    if (activeNumber == 1)
                    {
                        if (m_CmeDailyTryCount >= 1)
                            DownLoadATM();
                    }
                    else if (activeNumber == 2)
                    {
                        if (m_CmeMstTryCount >= 1)
                            DownLoadATM();
                    }
                    else if (activeNumber == 3)
                    {
                        if (m_CpFore8312TryCount >= GlobalVar.m_MoneyExCodeTable.Length)
                            DownLoadATM();
                    }
                    else if (activeNumber == 4)
                    {
                        if (m_CpSvr8300TryCount >= GlobalVar.m_WorldCodeTable.Length)
                            DownLoadATM();
                    }
                    else if (activeNumber == 5)
                    {
                        if (m_OptChartTryCount >= m_OptChartCodeArray.Length)
                            DownLoadATM();
                    }
                    else if (activeNumber == 6)
                    {
                        if (m_StockChartTryCount >= 1)
                            DownLoadATM();
                    }
                    else if (activeNumber == 7)
                    {
                        if (m_OptTodayTryCount >= m_CenterPriceCodeList.Count)
                            DownLoadATM();
                    }
                    else
                        DownLoadATM();
                }
                if (m_OptionAtmTryCount >= 1 && m_FutChartTryCount < 1)
                    DownloadFutChart();
                if (m_FutChartTryCount >= 1 && m_FutureMstTryCount < 1)
                    DownLoadFutureMst();
                if (m_FutureMstTryCount >= 1 && m_CpSvrNew7221TryCount < 1)
                    DownLoadCPSvrNew7221();
                ResetDownloadCount();
                PutRealTimeData();
            }
        }

        private int GetRequestRemainCount()
        {
            object remain = m_CpCybos.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_NONTRADE_REQUEST);
            int remainCount = Convert.ToInt32(remain);
            //Console.WriteLine(remain);
            return remainCount;
        }

        public void StartTimer()
        {
            timer.Start();
        }

        public void StopTimer()
        {
            timer.Stop();
        }

        public DownloadCenter(EasyTrader.ETDataSet a_EasyTraderDataSet)
        {
            m_CurDay = GlobalVar.DateToInt();
            m_EasyTraderDataSet = a_EasyTraderDataSet;
            ReadOpExpDate();
            //ReadOpCross();
            MakeOpCodeList();
            InitRealTimeDataObject();
            InitRequestDataObject();
            InitTimer();
        }

        public DownloadCenter()
        {
            m_CurDay = GlobalVar.DateToInt();
            ReadOpExpDate();
            //ReadOpCross();
            MakeOpCodeList();
            InitRealTimeDataObject();
            InitRequestDataObject();
            InitTimer();
        }

#endregion
#region Download Functions

        private void DownLoadOptToday()
        {
            if (m_Lock != false)
                return;
            Console.WriteLine("DownloadOptToday");

            m_Lock = true;
            EasyTrader.DataSet.CodePair code = m_OptChartCodeList[m_OptTodayTryCount];
            int curDay = Convert.ToInt32(code.Date);
            int[] fields = new int[] { 0, 1, 2, 3, 4, 5, 6, 8, 27, 29 };
            m_OptTodayFetcher.SetInputValue(0, code.Code);
            m_OptTodayFetcher.SetInputValue(1, '2');
            m_OptTodayFetcher.SetInputValue(2, curDay);
            m_OptTodayFetcher.SetInputValue(3, curDay);
            m_OptTodayFetcher.SetInputValue(4, 2);
            m_OptTodayFetcher.SetInputValue(5, fields);
            m_OptTodayFetcher.SetInputValue(6, 'D');
            m_OptTodayFetcher.SetInputValue(7, 1);

            try
            {
                // 데이터 수신 요청을 한다.
                m_OptTodayFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private bool first = false;

        private void DownLoadOptChart()
        {
            if (m_Lock != false)
                return;

            Lock = true;
            EasyTrader.DataSet.CodePair code = m_OptChartCodeList[m_OptChartTryCount];
            /*
            // 먼저 기존에 데이터 파일이 있는지 확인하고 있으면 받지 않는다.
            EasyTrader.DataSet.BarDataTable table = m_EasyTraderDataSet.FindOptTable(code.Code.ToString());
            if (table != null)
            {
                bool isExist = table.ReadFromXml(code.Date, code.Code);
                if (isExist == true)
                {
                    m_OptChartTryCount++;
                    m_Lock = false;
                    return;
                }
            }*/

            DateTime now = DateTime.Now;
            Console.WriteLine("SysTime Start" + now.Minute.ToString() + now.Second.ToString() );

            /*
            if (GlobalVar.OperationMode == GlobalVar.OperationModeSimul || first == true)
            {
                m_OptChartMethod = '1';
            }
            else
            {
                m_OptChartMethod = '2';
            }*/

            int exDay = Convert.ToInt32(code.Date);
            int[] fields = new int[] { 0, 1, 2, 3, 4, 5, 6, 8, 27, 29 };
            m_OptChartFetcher.SetInputValue(0, code.Code);
            m_OptChartFetcher.SetInputValue(1, m_OptChartMethod);
            m_OptChartFetcher.SetInputValue(2, exDay);
            m_OptChartFetcher.SetInputValue(3, exDay);
            m_OptChartFetcher.SetInputValue(4, 1);
            m_OptChartFetcher.SetInputValue(5, fields);
            m_OptChartFetcher.SetInputValue(6, m_OptChartUnit);
            m_OptChartFetcher.SetInputValue(7, m_OptChartCycle);

            try
            {
                // 데이터 수신 요청을 한다.
                m_OptChartFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private void DownLoadOptDay()
        {
            if (m_Lock != false)
                return;

            //GlobalVar.StateMessage = "데이터 수신중입니다. 잠시만 기다려 주세요.";

            Lock = true;
            string code = m_CenterPriceCodeList[m_OptDayTryCount].Code;
            int beginDay = FindRecentExpDay(m_CurDay);
            int baseDay = beginDay - 10;

            int openDay, preOpenDay;
            int today = Convert.ToInt32(m_CurDay);
            if (today == 0)
                today = GlobalVar.DateToInt();
            FindLastOpenDay(today, out openDay, out preOpenDay);

            int endDay = openDay;

            //int dayCount = GetElapDays(m_FutDayList);
            int[] fields = new int[] { 0, 1, 2, 3, 4, 5, 6, 8, 27, 29 };
            m_OptDayFetcher.SetInputValue(0, code);
            m_OptDayFetcher.SetInputValue(1, '1');
            m_OptDayFetcher.SetInputValue(2, endDay);
            m_OptDayFetcher.SetInputValue(3, baseDay);
            //m_OptDayChart.SetInputValue(4, dayCount);
            m_OptDayFetcher.SetInputValue(5, fields);
            m_OptDayFetcher.SetInputValue(6, 'D');
            m_OptDayFetcher.SetInputValue(7, 1);

            try
            {
                // 데이터 수신 요청을 한다.
                m_OptDayFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private void DownLoadFutDay()
        {
            if (m_Lock != false)
                return;

            Lock = true;

            GlobalVar.StateMessage = "데이터 수신중입니다. 잠시만 기다려 주세요.";

            //DateTime now = DateTime.Now;
            //Console.WriteLine(now.Second.ToString() + now.Millisecond.ToString() );

            int curDay = GlobalVar.DateToInt();
            object code = m_CpFutureCode.GetData(0, 0);
            int[] fields = new int[] { 0, 1, 2, 3, 4, 5, 6, 8, 27, 29 };
            m_FutDayFetcher.SetInputValue(0, code);
            m_FutDayFetcher.SetInputValue(1, '2');
            m_FutDayFetcher.SetInputValue(2, curDay);
            m_FutDayFetcher.SetInputValue(3, curDay);
            m_FutDayFetcher.SetInputValue(4, 40);
            m_FutDayFetcher.SetInputValue(5, fields);
            m_FutDayFetcher.SetInputValue(6, 'D');
            m_FutDayFetcher.SetInputValue(7, 1);

            try
            {
                // 데이터 수신 요청을 한다.
                m_FutDayFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private void DownLoadATM()
        {
            m_OptionAtmTryCount = 1;
            return;

            /*
            if (m_Lock != false)
                return;

            Lock = true;
            m_OptionAtmFetcher.Request();
             */ 
        }

        private void SetAtm()
        {
            int curDay = 0, preDay = 0;
            m_EasyTraderDataSet.FindLastOpenDay(Convert.ToInt32(m_CurDay), out curDay, out preDay);
            double atm = m_EasyTraderDataSet.CalcAtm(curDay);
            for (int i = 0; i < CenterPriceCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodeTable table = CenterPriceCodeList[i];
                string code = table.Code;
                string valCode = code.Substring(code.Length - 3, 3);
                string sideCode = code.Substring(0, 1);
                double codeVal = Convert.ToDouble(valCode);
                if (Math.Abs(codeVal - atm) <= 0.5)
                {
                    if (sideCode == "2")
                        GlobalVar.CATM = code;
                    else if (sideCode == "3")
                        GlobalVar.PATM = code;
                }
            }
        }

        // 현재 주어진 코드보다 한 행사가 높은 코드를 찾아서 반환한다.
        public bool GetCallUpDownCode(string a_CallCode, int a_Level, out string a_NewCode)
        {
            a_NewCode = "";
            int index = -1;
            for (int i = 0; i < m_CallPriceCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodeTable code = m_CallPriceCodeList[i];
                if (code.Code == a_CallCode)
                {
                    index = i;
                    break;
                }
            }
            if (index < 0)
                return false;
            index = index + a_Level;
            if (index < 0 || index > m_CallPriceCodeList.Count - 1)
                return false;

            EasyTrader.DataSet.CodeTable newCode = m_CallPriceCodeList[index];
            a_NewCode = newCode.Code;

            return true;
        }

        // 현재 주어진 코드보다 한 행사가 높은 코드를 찾아서 반환한다.
        public bool GetPutUpDownCode(string a_PutCode, int a_Level, out string a_NewCode)
        {
            a_NewCode = "";
            int index = -1;
            for (int i = 0; i < m_PutPriceCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodeTable code = m_PutPriceCodeList[i];
                if (code.Code == a_PutCode)
                {
                    index = i;
                    break;
                }
            }
            if (index < 0)
                return false;
            index = index + a_Level;
            if (index < 0 || index > m_PutPriceCodeList.Count - 1)
                return false;

            EasyTrader.DataSet.CodeTable newCode = m_PutPriceCodeList[index];
            a_NewCode = newCode.Code;

            return true;
        }


        public int FindInnerOuter(string a_OpCode)
        {
            int outVal = 0;
            string atmCode = m_CallATM;
            string atmPrice = atmCode.Substring(atmCode.Length - 3, 3);
            int atmValue = Convert.ToInt32(atmPrice);

            string sideCode = a_OpCode.Substring(0, 1);
            string priceCode = a_OpCode.Substring(a_OpCode.Length - 3, 3);
            int priceVal = Convert.ToInt32(priceCode);
            if (sideCode == "2")
            {
                if (priceVal > atmValue)
                    outVal = 1;
                else if (priceVal < atmValue)
                    outVal = -1;
            }
            else if (sideCode == "3")
            {
                if (priceVal < atmValue)
                    outVal = 1;
                else if (priceVal > atmValue)
                    outVal = -1;
            }

            return outVal;
        }

        public string GetCallAtm(object a_CurDay)
        {
            string atmcode = "";
            int curDay = 0, preDay = 0;
            m_EasyTraderDataSet.FindLastOpenDay(Convert.ToInt32(a_CurDay), out curDay, out preDay);
            double atm = m_EasyTraderDataSet.CalcAtm(curDay);
            for (int i = 0; i < CallPriceCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodeTable table = CallPriceCodeList[i];
                string code = table.Code;
                string valCode = code.Substring(code.Length - 3, 3);
                double codeVal = Convert.ToDouble(valCode);
                if (Math.Abs(codeVal - atm) <= 0.5)
                {
                    atmcode = code;
                    break;
                }
            }

            if (atmcode == "")
            {
                int p = 0;
                p = p + 1;
            }

            return atmcode;
        }

        public string GetCallAtm()
        {
            string atmcode = "";
            double atm = m_EasyTraderDataSet.CalcAtm();
            if (atm < 0)
                return atmcode;

            for (int i = 0; i < CallPriceCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodeTable table = CallPriceCodeList[i];
                string code = table.Code;
                string valCode = code.Substring(code.Length - 3, 3);
                double codeVal = Convert.ToDouble(valCode);
                if (Math.Abs(codeVal - atm) <= 0.5)
                {
                    atmcode = code;
                    break;
                }
            }
            return atmcode;
        }

        public string GetPutAtm(object a_CurDay)
        {
            string atmcode = "";
            int curDay = 0, preDay = 0;
            m_EasyTraderDataSet.FindLastOpenDay(Convert.ToInt32(a_CurDay), out curDay, out preDay);
            double atm = m_EasyTraderDataSet.CalcAtm(curDay);
            for (int i = 0; i < PutPriceCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodeTable table = PutPriceCodeList[i];
                string code = table.Code;
                string valCode = code.Substring(code.Length - 3, 3);
                double codeVal = Convert.ToDouble(valCode);
                if (Math.Abs(codeVal - atm) <= 0.5)
                {
                    atmcode = code;
                    break;
                }
            }

            return atmcode;
        }

        public string GetPutAtm()
        {
            string atmcode = "";
            double atm = m_EasyTraderDataSet.CalcAtm();
            if (atm < 0)
                return atmcode;

            for (int i = 0; i < PutPriceCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodeTable table = PutPriceCodeList[i];
                string code = table.Code;
                string valCode = code.Substring(code.Length - 3, 3);
                double codeVal = Convert.ToDouble(valCode);
                if (Math.Abs(codeVal - atm) <= 0.5)
                {
                    atmcode = code;
                    break;
                }
            }

            return atmcode;
        }

        private void DownLoadOptPastChart()
        {
            if (m_Lock != false)
                return;
            m_Lock = true;

            //GlobalVar.StateMessage = "데이터 수신중입니다. 잠시만 기다려 주세요.";

            EasyTrader.DataSet.CodePair code = m_OptPastCodeList[m_OptPastChartTryCount];
            Console.WriteLine(m_OptPastChartTryCount.ToString());

            // 먼저 기존에 데이터 파일이 있는지 확인하고 있으면 받지 않는다.
            bool isExist = m_BarTable.IsDataFileExist(code.Date, code.Code);
            if (isExist == true)
            {
                m_OptPastChartTryCount++;
                m_Lock = false;
                return;
            }
            int exDay = Convert.ToInt32(code.Date);
            int[] fields = new int[] { 0, 1, 2, 3, 4, 5, 6, 8, 27, 29 };
            m_OptPastChartFetcher.SetInputValue(0, code.Code);
            m_OptPastChartFetcher.SetInputValue(1, '1');
            m_OptPastChartFetcher.SetInputValue(2, exDay);
            m_OptPastChartFetcher.SetInputValue(3, exDay);
            //m_OptChartFetcher.SetInputValue(4, m_ChartTerm);
            m_OptPastChartFetcher.SetInputValue(5, fields);
            m_OptPastChartFetcher.SetInputValue(6, m_OptChartUnit);
            m_OptPastChartFetcher.SetInputValue(7, m_OptChartCycle);

            try
            {
                // 데이터 수신 요청을 한다.
                m_OptPastChartFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }


        private void DownloadCpFore8312()
        {
            if (m_Lock != false)
                return;

            m_Lock = true;
            string code = GlobalVar.m_MoneyExCodeTable[m_CpFore8312TryCount];
            m_CpFore8312Fetcher.SetInputValue(0, code);
            m_CpFore8312Fetcher.SetInputValue(1, '2');
            m_CpFore8312Fetcher.SetInputValue(2, 30);
            try
            {
                // 데이터 수신 요청을 한다.
                m_CpFore8312Fetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private void DownLoadCPSvrNew7221()
        {
            if (m_Lock != false)
                return;

            m_Lock = true;
            // 옵션, 선물 금액으로 설정
            m_CpSvrNew7221Fetcher.SetInputValue(0, '3');
            try
            {
                // 데이터 수신 요청을 한다.
                m_CpSvrNew7221Fetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }


        private void DownLoadFutureMst()
        {
            if (m_Lock != false)
                return;

            m_Lock = true;

            object code = m_CpFutureCode.GetData(0, 0);
            m_FutureMstFetcher.SetInputValue(0, code);
            try
            {
                // 데이터 수신 요청을 한다.
                m_FutureMstFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private void DownloadCpSvr8300()
        {
            if (m_Lock != false)
                return;

            m_Lock = true;
            string code = GlobalVar.m_WorldCodeTable[m_CpSvr8300TryCount];
            GlobalVar.WorldCurDownloaded = false;
            m_CpSvr8300Fetcher.SetInputValue(0, code);
            m_CpSvr8300Fetcher.SetInputValue(1, 'D');
            m_CpSvr8300Fetcher.SetInputValue(3, 30);
            try
            {
                // 데이터 수신 요청을 한다.
                m_CpSvr8300Fetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private void DownloadFutChart()
        {
            if (m_Lock != false)
                return;

            m_Lock = true;

            object code = m_CpFutureCode.GetData(0, 0);
            int[] fields = new int[] { 0, 1, 2, 3, 4, 5, 6, 8, 27, 29 };
            m_FutChartFetcher.SetInputValue(0, code);
            m_FutChartFetcher.SetInputValue(1, '1');
            m_FutChartFetcher.SetInputValue(2, m_CurDay);
            m_FutChartFetcher.SetInputValue(3, m_CurDay);
            m_FutChartFetcher.SetInputValue(5, fields);
            m_FutChartFetcher.SetInputValue(6, 'm');
            m_FutChartFetcher.SetInputValue(7, m_FutChartCycle);

            // 데이터 수신 요청을 한다.
            try
            {
                // 데이터 수신 요청을 한다.
                m_FutChartFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private void DownloadCmeDaily()
        {
            if (m_Lock != false)
                return;

            m_Lock = true;

            object futureCode = m_CpFutureCode.GetData(0, 0);
            m_CmeDailyFetcher.SetInputValue(0, futureCode);
            //m_CmeDaily.Request();
            try
            {
                // 데이터 수신 요청을 한다.
                m_CmeDailyFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private void DownLoadCmeMst()
        {
            if (m_Lock != false)
                return;

            m_Lock = true;

            CmeMstTable curTable = m_EasyTraderDataSet.GetCmeMstTable();
            int curDayIndex = GlobalVar.NightIndex();
            int curRowCount = curTable.GetRowCount();
            object futureCode = m_CpFutureCode.GetData(0, 0);
            int curDate = GlobalVar.DateToInt();
            // 현재 테이블의 행개수가 현재 인덱스+1 보다 작으면 모자른 행만큼 더 추가해야 한다.
            // 장 중간에 시작했을 때에 라도 행개수가 부족함이 없이 하기 위해서이다.
            // 0번행은 시초가가 들어가도록 한다.
            if (curRowCount < curDayIndex + 1)
            {
                int addCount = (curDayIndex + 1) - curRowCount;
                // 필요한 개수만큼 추가해 준다.
                for (int i = 0; i < addCount; i++)
                {
                    // GlobalVar.CmeMstTableColSize
                    object[] CmeMstBuffer = new object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    curTable.AddRow(CmeMstBuffer);
                }
            }
            object code = m_CpFutureCode.GetData(0, 0);
            m_CmeMstFetcher.SetInputValue(0, code);
            try
            {
                // 데이터 수신 요청을 한다.
                m_CmeMstFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private void DownloadStockChart()
        {
            if (m_Lock != false)
                return;

            m_Lock = true;

            string code = GlobalVar.m_StockCodeTable[m_StockChartIndex];

            int[] fields = new int[] { 0, 1, 2, 3, 4, 5, 6, 8 };
            m_StockChartFetcher.SetInputValue(0, code);
            m_StockChartFetcher.SetInputValue(1, '1');
            m_StockChartFetcher.SetInputValue(2, m_CurDay);
            m_StockChartFetcher.SetInputValue(3, m_CurDay);
            m_StockChartFetcher.SetInputValue(5, fields);
            m_StockChartFetcher.SetInputValue(6, 'm');
            m_StockChartFetcher.SetInputValue(7, m_StockChartCycle);

            try
            {
                // 데이터 수신 요청을 한다.
                m_StockChartFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

#endregion
#region Request OnReceived Handlers

        public void OnReceived_OptToday()
        {
            Console.WriteLine("OnReceived_OptToday");
            m_Lock = false;
            object opCode = m_OptTodayFetcher.GetHeaderValue(0);
            object count = m_OptTodayFetcher.GetHeaderValue(3);
            if (Convert.ToInt32(count) >= 2)
            {
                object curVal = m_OptTodayFetcher.GetHeaderValue(7);
                object open = m_OptTodayFetcher.GetDataValue(2, 0);
                object high = m_OptTodayFetcher.GetDataValue(3, 0);
                object low = m_OptTodayFetcher.GetDataValue(4, 0);
            }
            m_OptTodayTryCount++;
        }

        private bool done = false ;
        public void OnReceived_OptChart()
        {
            m_Lock = false;
            DateTime now = DateTime.Now;


            object count = m_OptChartFetcher.GetHeaderValue(3);
            int dataCount = Convert.ToInt32(count);

            //DateTime now = DateTime.Now;

            if (dataCount > 0)
            {
                object code = m_OptChartFetcher.GetHeaderValue(0);
                Console.WriteLine(now.Minute.ToString() + now.Second.ToString());
                Console.WriteLine(code.ToString());
                EasyTrader.DataSet.BarDataTable table = m_EasyTraderDataSet.FindOptTableInCodeList(code.ToString());
                //if (table != null)
                //    Console.WriteLine("before" + table.TableName);
                if (table != null)
                {
                    // 일단 테이블의 모든 항목을 없앤다.
                    table.Clear();
                    // 테이블 이름을 넣어 준다.
                    table.TableName = code.ToString();
                    //Console.WriteLine("after" + table.TableName);

                    object[] data = new object[6];
                    data[0] = m_OptChartFetcher.GetDataValue(0, dataCount - 1);
                    data[1] = "900";//m_OptChartFetcher.GetDataValue(1, dataCount - 1);
                    data[2] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // open
                    data[3] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // high
                    data[4] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // low
                    data[5] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // close
                    table.AddRow(data);

                    for (int i = dataCount - 1; i >= 0; i--)
                    {
                        data = new object[6];
                        data[0] = m_OptChartFetcher.GetDataValue(0, i);
                        data[1] = m_OptChartFetcher.GetDataValue(1, i);
                        data[2] = m_OptChartFetcher.GetDataValue(2, i); // open
                        data[3] = m_OptChartFetcher.GetDataValue(3, i); // high
                        data[4] = m_OptChartFetcher.GetDataValue(4, i); // low
                        data[5] = m_OptChartFetcher.GetDataValue(5, i); // close
                        table.AddRow(data);
                        if (i == 0)
                        {
                            int c = 0;
                            c = c + 1;
                        }
                    }
                }
            }

            /*
            if (GlobalVar.OperationMode == GlobalVar.OperationModeSimul || first == true)
            {
                object count = m_OptChartFetcher.GetHeaderValue(3);
                int dataCount = Convert.ToInt32(count);

                //DateTime now = DateTime.Now;

                if (dataCount > 0)
                {
                    object code = m_OptChartFetcher.GetHeaderValue(0);
                    Console.WriteLine(now.Minute.ToString() + now.Second.ToString());
                    Console.WriteLine(code.ToString());
                    EasyTrader.DataSet.BarDataTable table = m_EasyTraderDataSet.FindOptTableInCodeList(code.ToString());
                    //if (table != null)
                    //    Console.WriteLine("before" + table.TableName);
                    if (table != null)
                    {
                        // 일단 테이블의 모든 항목을 없앤다.
                        table.Clear();
                        // 테이블 이름을 넣어 준다.
                        table.TableName = code.ToString();
                        //Console.WriteLine("after" + table.TableName);

                        object[] data = new object[6];
                        data[0] = m_OptChartFetcher.GetDataValue(0, dataCount - 1);
                        data[1] = "900";//m_OptChartFetcher.GetDataValue(1, dataCount - 1);
                        data[2] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // open
                        data[3] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // high
                        data[4] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // low
                        data[5] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // close
                        table.AddRow(data);

                        for (int i = dataCount - 1; i >= 0; i--)
                        {
                            data = new object[6];
                            data[0] = m_OptChartFetcher.GetDataValue(0, i);
                            data[1] = m_OptChartFetcher.GetDataValue(1, i);
                            data[2] = m_OptChartFetcher.GetDataValue(2, i); // open
                            data[3] = m_OptChartFetcher.GetDataValue(3, i); // high
                            data[4] = m_OptChartFetcher.GetDataValue(4, i); // low
                            data[5] = m_OptChartFetcher.GetDataValue(5, i); // close
                            table.AddRow(data);
                            if (i == 0)
                            {
                                int c = 0;
                                c = c + 1;
                            }
                        }
                    }
                }
            }
            else
            {
                object count = m_OptChartFetcher.GetHeaderValue(3);
                int dataCount = Convert.ToInt32(count);


                if (dataCount > 0)
                {
                    object code = m_OptChartFetcher.GetHeaderValue(0);
                    Console.WriteLine(now.Minute.ToString() + now.Second.ToString());
                    Console.WriteLine(code.ToString());
                    EasyTrader.DataSet.BarDataTable table = m_EasyTraderDataSet.FindOptTableInCodeList(code.ToString());
                    //if (table != null)
                    //    Console.WriteLine("before" + table.TableName);
                    if (table != null)
                    {
                        // 일단 테이블의 모든 항목을 없앤다.
                        //table.Clear();
                        // 테이블 이름을 넣어 준다.
                        table.TableName = code.ToString();
                        int rowCount = table.GetRowCount();
                        object oTime = m_OptChartFetcher.GetDataValue(1, dataCount - 1);
                        int curIndex = GlobalVar.DayIndex(oTime.ToString());

                        if (rowCount < curIndex + 2)
                        {
                            int delta = curIndex + 2 - rowCount;
                            for (int i = 0; i <= delta; i++)
                            {
                                object[] data = new object[6];
                                table.AddRow(data);
                            }
                        }
                        DataRow curRow = null;
                        if (curIndex <= 1)
                        {
                            curRow = table.Rows[0];
                            curRow[0] = m_OptChartFetcher.GetDataValue(0, dataCount - 1);
                            curRow[1] = "900";//m_OptChartFetcher.GetDataValue(1, dataCount - 1);
                            curRow[2] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // open
                            curRow[3] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // high
                            curRow[4] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // low
                            curRow[5] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // close

                            curRow = table.Rows[curIndex];
                            curRow[0] = m_OptChartFetcher.GetDataValue(0, dataCount - 1);
                            curRow[1] = m_OptChartFetcher.GetDataValue(1, dataCount - 1);
                            curRow[2] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // open
                            curRow[3] = m_OptChartFetcher.GetDataValue(3, dataCount - 1); // high
                            curRow[4] = m_OptChartFetcher.GetDataValue(4, dataCount - 1); // low
                            curRow[5] = m_OptChartFetcher.GetDataValue(5, dataCount - 1); // close
                        }
                        else
                        {
                            curRow = table.Rows[curIndex];
                            curRow[0] = m_OptChartFetcher.GetDataValue(0, dataCount - 1);
                            curRow[1] = m_OptChartFetcher.GetDataValue(1, dataCount - 1);
                            curRow[2] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // open
                            curRow[3] = m_OptChartFetcher.GetDataValue(3, dataCount - 1); // high
                            curRow[4] = m_OptChartFetcher.GetDataValue(4, dataCount - 1); // low
                            curRow[5] = m_OptChartFetcher.GetDataValue(5, dataCount - 1); // close
                        }

                        //Console.WriteLine("after" + table.TableName);
                        object[] data = new object[6];
                        data[0] = m_OptChartFetcher.GetDataValue(0, dataCount - 1);
                        data[1] = "900";//m_OptChartFetcher.GetDataValue(1, dataCount - 1);
                        data[2] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // open
                        data[3] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // high
                        data[4] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // low
                        data[5] = m_OptChartFetcher.GetDataValue(2, dataCount - 1); // close
                        table.AddRow(data);

                        for (int i = dataCount - 1; i >= 0; i--)
                        {
                            data = new object[6];
                            data[0] = m_OptChartFetcher.GetDataValue(0, i);
                            data[1] = m_OptChartFetcher.GetDataValue(1, i);
                            data[2] = m_OptChartFetcher.GetDataValue(2, i); // open
                            data[3] = m_OptChartFetcher.GetDataValue(3, i); // high
                            data[4] = m_OptChartFetcher.GetDataValue(4, i); // low
                            data[5] = m_OptChartFetcher.GetDataValue(5, i); // close
                            table.AddRow(data);
                            if (i == 0)
                            {
                                int c = 0;
                                c = c + 1;
                            }
                        }
                    }
                }
            }
            */
            m_OptChartTryCount++;
            //DateTime now = DateTime.Now;
            //Console.WriteLine("SysTime Downloading = " + now.Minute.ToString() + now.Second.ToString());

            if (m_OptChartTryCount >= m_OptChartCodeArray.Length)
            {
                m_AllOptChartDataDownloaded = true;

                if (first == true)
                    first = false;

                if (done == false)
                {
                    //DateTime now = DateTime.Now;
                    Console.WriteLine("SysTimeEnd = " + now.Minute.ToString() + now.Second.ToString());
                    done = true;
                }
            }
        }

        public void OnReceived_OptPastChart()
        {
            m_Lock = false;
            object count = m_OptPastChartFetcher.GetHeaderValue(3);
            int dataCount = Convert.ToInt32(count);

            if (dataCount > 0)
            {
                // 먼저 모든 데이터를 없애준다.
                m_BarTable.Clear();

                object code = m_OptPastChartFetcher.GetHeaderValue(0);
                object date = m_OptPastChartFetcher.GetDataValue(0, 0);
                for (int i = dataCount - 1; i >= 0; i--)
                {
                    object[] data = new object[6];
                    data[0] = m_OptPastChartFetcher.GetDataValue(0, i);
                    data[1] = m_OptPastChartFetcher.GetDataValue(1, i);
                    data[2] = m_OptPastChartFetcher.GetDataValue(2, i);
                    data[3] = m_OptPastChartFetcher.GetDataValue(3, i);
                    data[4] = m_OptPastChartFetcher.GetDataValue(4, i);
                    data[5] = m_OptPastChartFetcher.GetDataValue(5, i);
                    m_BarTable.AddRow(data);
                }
                string tableName = "OptTable_" + code.ToString();
                m_BarTable.TableName = tableName;
                // 바로 XML로 저장 시킨다.
                m_BarTable.SaveTableToXml(date, code);
            }
            m_OptPastChartTryCount++;
        }

        public void OnReceived_OptDay()
        {
            m_Lock = false;

            object count = m_OptDayFetcher.GetHeaderValue(3);
            int dataCount = Convert.ToInt32(count);
            if (dataCount == 0)
            {
                m_OptDayTryCount++;
                return;
            }

            object code = m_OptDayFetcher.GetHeaderValue(0);
            // We need as many counts as the numbers of price.
            BarDataItemList newCol = new BarDataItemList();
            m_EasyTraderDataSet.OptDayDataList.Add(newCol);
            BarDataItemList curCol = m_EasyTraderDataSet.OptDayDataList[m_OptDayTryCount];
            List<BarDataItem> dataList = curCol.DataList;

            object curTime = m_OptDayFetcher.GetDataValue(1, 0);

            curCol.Code = code;
            curCol.Date = m_CurDay;
            curCol.Time = curTime;

            for (int i = 0; i < dataCount; i++)
            {
                object date = m_OptDayFetcher.GetDataValue(0, i);
                object time = m_OptDayFetcher.GetDataValue(1, i);
                object open = m_OptDayFetcher.GetDataValue(2, i);
                object high = m_OptDayFetcher.GetDataValue(3, i);
                object low = m_OptDayFetcher.GetDataValue(4, i);
                object close = m_OptDayFetcher.GetDataValue(5, i);
                BarDataItem newItem = new BarDataItem();
                newItem.Date = date;
                newItem.Time = time;
                newItem.Open = open;
                newItem.High = high;
                newItem.Low = low;
                newItem.Close = close;
                dataList.Add(newItem);
            }

            m_OptDayTryCount++;
        }

        public void InitDownloadCount()
        {
            m_EasyTraderDataSet.OptDayDataList.Clear();
            m_EasyTraderDataSet.FutDayList.Clear();
            m_FutDayTryCount = 0;
            m_OptDayTryCount = 0;
            m_FutChartTryCount = 0;
            m_FutureMstTryCount = 0;
            m_CpSvrNew7221TryCount = 0;
            GlobalVar.AllDataDownloaded = false;
        }

        public void OnReceived_FutDay()
        {
            Lock = false;

            object count = m_FutDayFetcher.GetHeaderValue(3);
            int dataCount = Convert.ToInt32(count);

            for (int i = 0; i < dataCount; i++)
            {
                BarDataItem item = new BarDataItem();
                item.Date = m_FutDayFetcher.GetDataValue(0, i);
                item.Time = m_FutDayFetcher.GetDataValue(1, i);
                item.Open = m_FutDayFetcher.GetDataValue(2, i);
                item.High = m_FutDayFetcher.GetDataValue(3, i);
                item.Low = m_FutDayFetcher.GetDataValue(4, i);
                item.Close = m_FutDayFetcher.GetDataValue(5, i);
                m_EasyTraderDataSet.FutDayList.Add(item);
            }

            if (GlobalVar.OperationMode == GlobalVar.OperationModeSimul)
                SetDay(m_CurDay);
            else
                SetDay(0);
            // 선물 일자별 데이터를 받으면 일자별 옵션 행사가 코드를 만들어 준다.
            MakeOptPastCodeList();
            // 옵션 차트 데이터 코드 목록을 결정해 준다.
            MakeOptChartCodeList();
            // 여기서 옵션 차트를 위한 데이터 목록을 만들어 준다.
            if (m_EasyTraderDataSet.OptChartTableCount == 0)
                m_EasyTraderDataSet.CreateOptTables();

            GlobalVar.CATM = m_CallATM = GetCallAtm(m_CurDay);
            GlobalVar.PATM = m_PutATM = GetPutAtm(m_CurDay);

            m_FutDayTryCount++;
        }

        public void OnReceived_OptionATM()
        {
            Lock = false;


            object count = m_OptionAtmFetcher.GetHeaderValue(0);
            if (Convert.ToInt32(count) > 0)
            {
                m_ATMArray = new string[Convert.ToInt32(count)];
                for (int i = 0; i < Convert.ToInt32(count); i++)
                {
                    m_ATMArray[i] = m_OptionAtmFetcher.GetDataValue(0, i).ToString();
                }
                if (Convert.ToInt32(count) >= 1)
                    GlobalVar.CATM = m_ATMArray[0];
                if (Convert.ToInt32(count) >= 5)
                    GlobalVar.PATM = m_ATMArray[4];
            }

            m_OptionAtmTryCount++;
        }

        public void OnReceived_CpSvr8300()
        {
            m_Lock = false;

            string worldCode = m_CpSvr8300Fetcher.GetHeaderValue(0).ToString();
            int dataCount = Convert.ToInt32(m_CpSvr8300Fetcher.GetHeaderValue(3));
            EasyTrader.DataSet.ETDataTable curTable = m_EasyTraderDataSet.GetWorldCurTable(worldCode);
            if (curTable == null)
                return;
            curTable.Clear();

            for (int j = dataCount - 1, i = 0; j >= 0; j--, i++)
            {
                object[] data = new object[8];
                data[0] = i;
                data[1] = i;
                data[2] = m_CpSvr8300Fetcher.GetDataValue(0, j); // 날짜
                data[3] = m_CpSvr8300Fetcher.GetDataValue(1, j); // 시가
                data[4] = m_CpSvr8300Fetcher.GetDataValue(2, j); // 고가
                data[5] = m_CpSvr8300Fetcher.GetDataValue(3, j); // 저가
                data[6] = m_CpSvr8300Fetcher.GetDataValue(4, j); // 종가
                data[7] = m_CpSvr8300Fetcher.GetDataValue(5, j); // 거래량
                curTable.AddRow(data);
            }
            GlobalVar.WorldCurDownloaded = true;
            m_CpSvr8300TryCount++;
        }

        public void OnReceived_Cp8312()
        {
            m_Lock = false;

            string code = m_CpFore8312Fetcher.GetHeaderValue(0).ToString();
            int dataCount = Convert.ToInt32(m_CpFore8312Fetcher.GetHeaderValue(2));
            EasyTrader.DataSet.FXKRWTable curTable = m_EasyTraderDataSet.GetFXKRWTable();
            if (curTable == null)
                return;
            // 모든 데이터를 없애준다.
            curTable.Clear();
            for (int j = dataCount - 1, i = 0; j >= 0; j--, i++)
            {
                object[] data = new object[6];
                data[0] = i;
                data[1] = m_CpFore8312Fetcher.GetDataValue(0, j); // 날짜
                data[2] = m_CpFore8312Fetcher.GetDataValue(1, j); // 지수현재가
                data[3] = m_CpFore8312Fetcher.GetDataValue(2, j); // 등락
                data[4] = m_CpFore8312Fetcher.GetDataValue(3, j); // 등락율
                data[5] = m_CpFore8312Fetcher.GetDataValue(4, j); // 거래량
                curTable.AddRow(data);
            }
            GlobalVar.Cp8312DataDownloaded = true;
            m_CpFore8312TryCount++;
        }

        public void OnReceived_CmeDaily()
        {
            m_Lock = false;

            string cmeCode = m_CmeDailyFetcher.GetHeaderValue(0).ToString();
            int dataCount = Convert.ToInt32(m_CmeDailyFetcher.GetHeaderValue(1));
            EasyTrader.DataSet.CmeDailyTable curTable = m_EasyTraderDataSet.GetCmeDailyTable();
            if (curTable == null)
                return;
            // 모든 데이터를 없애준다.
            curTable.Clear();
            for (int j = dataCount - 1, i = 0; j >= 0; j--, i++)
            {
                object[] data = new object[13];
                data[0] = i;
                data[1] = i;
                data[2] = m_CmeDailyFetcher.GetDataValue(0, j); // 날짜
                data[3] = m_CmeDailyFetcher.GetDataValue(1, j); // 시가
                data[4] = m_CmeDailyFetcher.GetDataValue(2, j); // 고가
                data[5] = m_CmeDailyFetcher.GetDataValue(3, j); // 저가
                data[6] = m_CmeDailyFetcher.GetDataValue(4, j); // 종가
                data[7] = m_CmeDailyFetcher.GetDataValue(6, j); // 누적거래량
                data[8] = m_CmeDailyFetcher.GetDataValue(11, j); // CME시가
                data[9] = m_CmeDailyFetcher.GetDataValue(12, j); // CME고가
                data[10] = m_CmeDailyFetcher.GetDataValue(13, j); // CME저가
                data[11] = m_CmeDailyFetcher.GetDataValue(14, j); // CME종가
                data[12] = m_CmeDailyFetcher.GetDataValue(16, j); // CME누적거래량
                curTable.AddRow(data);
                if (j == 0)
                {
                    double p = 0;
                    p = p + 1;
                    object val = m_CmeDailyFetcher.GetDataValue(12, 0);
                    p = Convert.ToDouble(val);
                }
            }
            m_CmeDailyTryCount++;
            GlobalVar.CmeDailyDataDownloaded = true;
        }

        public void OnReceived_FutChart()
        {
            m_Lock = false;

            FutOptChartTable curTable = m_EasyTraderDataSet.GetFutOptChartTable();
            if (curTable == null)
            {
                GlobalVar.FutOptChartDataDownloaded = true;
                m_FutChartTryCount++;
                return;
            }

            // 수신 개수
            object dataCount = m_FutChartFetcher.GetHeaderValue(3);
            if (Convert.ToInt32(dataCount) == 0)
            {
                GlobalVar.FutOptChartDataDownloaded = true;
                m_FutChartTryCount++;
                return;
            }
            #region Security Code
            object curDate = m_FutChartFetcher.GetDataValue(0, Convert.ToInt32(dataCount) - 1); // 날짜
            string dateString = curDate.ToString();
            string yearStr = dateString.Substring(0, 4);
            string monthStr = dateString.Substring(4, 2);
            int curYear = Convert.ToInt32(yearStr);
            int curMonth = Convert.ToInt32(monthStr);
            DateTime now = DateTime.Now;
            if (now.Year == GlobalVar.YearLimit && now.Month >= GlobalVar.MonthLimit)
            {
                return;
            }
            #endregion
            int curRowCount = curTable.Rows.Count;
            // 현재 테이블의 행개수가 현재 인덱스+1 보다 작으면 모자른 행만큼 더 추가해야 한다.
            // 장 중간에 시작했을 때에 라도 행개수가 부족함이 없이 하기 위해서이다.
            // 0번행은 시초가가 들어가도록 한다.

            // 필요한 개수만큼 추가해 준다.
            for (int i = 0; i <= GlobalVar.MaxDayIndex + 10; i++)
            {
                // GlobalVar.FutOptChartTableColSize
                if (curTable.GetRowCount() == Convert.ToInt32(dataCount) + 1)
                    break;

                object[] FutOptChartBuffer = new object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                curTable.AddRow(FutOptChartBuffer);
            }


            // 첫번째 요소는 항상 시가를 받도록 한다.
            DataRow curRow = curTable.Rows[0];
            curRow[2] = m_FutChartFetcher.GetDataValue(0, Convert.ToInt32(dataCount) - 1); // 날짜
            curRow[3] = "900"; // m_FutChartFetcher.GetDataValue(1, Convert.ToInt32(dataCount) - 1); // 시간
            curRow[4] = m_FutChartFetcher.GetDataValue(2, Convert.ToInt32(dataCount) - 1); // 시가
            curRow[5] = m_FutChartFetcher.GetDataValue(2, Convert.ToInt32(dataCount) - 1); // 고가
            curRow[6] = m_FutChartFetcher.GetDataValue(2, Convert.ToInt32(dataCount) - 1); // 저가
            curRow[7] = m_FutChartFetcher.GetDataValue(2, Convert.ToInt32(dataCount) - 1); // 종가
            curRow[8] = m_FutChartFetcher.GetDataValue(7, Convert.ToInt32(dataCount) - 1); // 거래량
            curRow[9] = m_FutChartFetcher.GetDataValue(8, Convert.ToInt32(dataCount) - 1); // 미결제약정
            curRow[10] = m_FutChartFetcher.GetDataValue(9, Convert.ToInt32(dataCount) - 1); // 베이시스
            curRow[0] = 0; // BarIndex
            curRow[1] = 0; // DayIndex
            // 데이터를 가져오지 못하면 아무일도 하지 않는다.
            if (Convert.ToInt32(dataCount) != 0)
            {
                for (int i = Convert.ToInt32(dataCount) - 1, j = 1; i > -1; i--, j++)
                {
                    curRow = curTable.Rows[j];
                    curRow[2] = m_FutChartFetcher.GetDataValue(0, i); // 날짜
                    curRow[3] = m_FutChartFetcher.GetDataValue(1, i); // 시간
                    curRow[4] = m_FutChartFetcher.GetDataValue(2, i); // 시가
                    curRow[5] = m_FutChartFetcher.GetDataValue(3, i); // 고가
                    curRow[6] = m_FutChartFetcher.GetDataValue(4, i); // 저가
                    curRow[7] = m_FutChartFetcher.GetDataValue(5, i); // 종가
                    curRow[8] = m_FutChartFetcher.GetDataValue(7, i); // 거래량
                    curRow[9] = m_FutChartFetcher.GetDataValue(8, i); // 미결제약정
                    curRow[10] = m_FutChartFetcher.GetDataValue(9, i); // 베이시스
                    int dayIndex = GlobalVar.DayIndex();
                    curRow[0] = j; // BarIndex
                    curRow[1] = dayIndex; // DayIndex
                }
                GlobalVar.FutOptChartDataDownloaded = true;
            }

            m_FutChartTryCount++;
            
        }

        public void OnReceived_FutureMst()
        {
            m_Lock = false;

            FutureMstTable curTable = m_EasyTraderDataSet.GetFutureMstTable();
            object curTime = m_FutureMstFetcher.GetHeaderValue(82); // 시각
            int curRowCount = curTable.Rows.Count;
            int curRowIndex = GlobalVar.DayIndex(curTime.ToString());
            // 현재 테이블의 행개수가 현재 인덱스+1 보다 작으면 모자른 행만큼 더 추가해야 한다.
            // 장 중간에 시작했을 때에 라도 행개수가 부족함이 없이 하기 위해서이다.
            // 0번행은 시초가가 들어가도록 한다.
            if (curRowCount < curRowIndex + 1)
            {
                int addCount = (curRowIndex + 1) - curRowCount;
                // 필요한 개수만큼 추가해 준다.
                for (int i = 0; i < addCount; i++)
                {
                    // GlobalVar.FutureMstTableColSize
                    object[] FutureMstBuffer = new object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    curTable.AddRow(FutureMstBuffer);
                }
            }
            DataRow curRow = null;
            int intTime = Convert.ToInt32(curTime);
            int openTime = GlobalVar.TimeToInt(GlobalVar.DayOpenTime, 0);
            curRowCount = curTable.Rows.Count;

            // 시간이 바뀔때 현재 정보를 맨 처음에 넣어 준다.
            if (intTime >= openTime && curRowCount >= 1 && FutureMstOpenSet == false)
            {
                curRow = curTable.Rows[0];
                curRow[2] = m_FutureMstFetcher.GetHeaderValue(0); // 선물코드
                curRow[3] = m_FutureMstFetcher.GetHeaderValue(82); // 시각
                curRow[4] = m_FutureMstFetcher.GetHeaderValue(72); // 시가
                curRow[5] = m_FutureMstFetcher.GetHeaderValue(73); // 고가
                curRow[6] = m_FutureMstFetcher.GetHeaderValue(71); // 현재가
                curRow[7] = m_FutureMstFetcher.GetHeaderValue(74); // 저가
                curRow[8] = m_FutureMstFetcher.GetHeaderValue(47); // 매도총호가수량
                curRow[9] = m_FutureMstFetcher.GetHeaderValue(53); // 매도총호가건수
                curRow[10] = m_FutureMstFetcher.GetHeaderValue(64); // 매수총호가수량
                curRow[11] = m_FutureMstFetcher.GetHeaderValue(70); // 매수총호가건수
                curRow[0] = 0; // BarIndex
                curRow[1] = 0; // DayIndex
                FutureMstOpenSet = true;
            }

            try
            {
                if (curRowIndex > curRowCount - 1)
                    return;

                curRow = curTable.Rows[curRowIndex];
                curRow[2] = m_FutureMstFetcher.GetHeaderValue(0); // 선물코드
                curRow[3] = m_FutureMstFetcher.GetHeaderValue(82); // 시각
                curRow[4] = m_FutureMstFetcher.GetHeaderValue(72); // 시가
                curRow[5] = m_FutureMstFetcher.GetHeaderValue(73); // 고가
                curRow[6] = m_FutureMstFetcher.GetHeaderValue(71); // 현재가
                curRow[7] = m_FutureMstFetcher.GetHeaderValue(74); // 저가
                curRow[8] = m_FutureMstFetcher.GetHeaderValue(47); // 매도총호가수량
                curRow[9] = m_FutureMstFetcher.GetHeaderValue(53); // 매도총호가건수
                curRow[10] = m_FutureMstFetcher.GetHeaderValue(64); // 매수총호가수량
                curRow[11] = m_FutureMstFetcher.GetHeaderValue(70); // 매수총호가건수
                curRow[0] = curRowIndex; // BarIndex
                curRow[1] = curRowIndex; // DayIndex
                GlobalVar.FutureMstDataDownloaded = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            m_FutureMstTryCount++;
        }

        public void OnReceived_CpSvrNew7221()
        {
            m_Lock = false;

            CPSvrNew7221Table curTable = m_EasyTraderDataSet.GetCPSvrNew7221Table();
            if (curTable == null)
            {
                m_CpSvrNew7221TryCount++;
                GlobalVar.CPSvrNew7221DataDownloaded = true;
                return;
            }
            int curRowCount = curTable.GetRowCount();

            object curTime = m_CpSvrNew7221Fetcher.GetHeaderValue(0); // 시각
            //int curRowIndex = GlobalVar.DayIndex(curTime.ToString());
            int curRowIndex = GlobalVar.DayIndex();

            // 현재 테이블의 행개수가 현재 인덱스+1 보다 작으면 모자른 행만큼 더 추가해야 한다.
            // 장 중간에 시작했을 때에 라도 행개수가 부족함이 없이 하기 위해서이다.
            // 0번행은 시초가가 들어가도록 한다.
            if (curRowCount < curRowIndex + 1)
            {
                int addCount = (curRowIndex + 1) - curRowCount;
                // 필요한 개수만큼 추가해 준다.
                for (int i = 0; i < addCount; i++)
                {
                    // GlobalVar.CPSvrNew7221TableColSize
                    object[] CPSvrNew7221Buffer = new object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    curTable.AddRow(CPSvrNew7221Buffer);
                }
            }

            DataRow curRow = null;
            int intTime = Convert.ToInt32(curTime);
            int openTime = GlobalVar.TimeToInt(GlobalVar.DayOpenTime, 0);
            curRowCount = curTable.GetRowCount();


            // 시간이 바뀔때 현재 정보를 맨 처음에 넣어 준다.
            if (intTime >= openTime && curRowCount >= 1 && CPSvrNew7221OpenSet == false)
            {
                curRow = curTable.Rows[0];
                curRow[2] = m_CpSvrNew7221Fetcher.GetHeaderValue(0); // 시각
                curRow[3] = m_CpSvrNew7221Fetcher.GetDataValue(2, 0); // 코스피개인순매수
                curRow[4] = m_CpSvrNew7221Fetcher.GetDataValue(5, 0); // 코스피외국인순매수
                curRow[5] = m_CpSvrNew7221Fetcher.GetDataValue(8, 0); // 코스피기관계순매수
                curRow[6] = m_CpSvrNew7221Fetcher.GetDataValue(17, 0); // 코스피투신순매수
                curRow[7] = m_CpSvrNew7221Fetcher.GetDataValue(26, 0); // 코스피기금순매수
                curRow[8] = m_CpSvrNew7221Fetcher.GetDataValue(29, 0); // 코스피국가순매수
                curRow[9] = m_CpSvrNew7221Fetcher.GetDataValue(2, 2); // 선물 개인 순매수
                curRow[10] = m_CpSvrNew7221Fetcher.GetDataValue(5, 2); // 선물 외국인 순매수
                curRow[11] = m_CpSvrNew7221Fetcher.GetDataValue(8, 2); // 선물 기관계 순매수
                curRow[12] = m_CpSvrNew7221Fetcher.GetDataValue(2, 3); // 개인옵션콜 순매수
                curRow[13] = m_CpSvrNew7221Fetcher.GetDataValue(5, 3); // 외국인옵션콜 순매수
                curRow[14] = m_CpSvrNew7221Fetcher.GetDataValue(8, 3); // 기관계옵션콜 순매수
                curRow[15] = m_CpSvrNew7221Fetcher.GetDataValue(2, 4); // 개인옵션풋 순매수
                curRow[16] = m_CpSvrNew7221Fetcher.GetDataValue(5, 4); // 외국인옵션풋 순매수
                curRow[17] = m_CpSvrNew7221Fetcher.GetDataValue(8, 4); // 기관계옵션풋 순매수
                curRow[0] = 0;
                curRow[1] = 0;
                CPSvrNew7221OpenSet = true;
            }

            try
            {
                if (curRowIndex > curRowCount - 1)
                    return;

                curRow = curTable.Rows[curRowIndex];
                curRow[2] = m_CpSvrNew7221Fetcher.GetHeaderValue(0); // 시각
                curRow[3] = m_CpSvrNew7221Fetcher.GetDataValue(2, 0); // 코스피개인순매수
                curRow[4] = m_CpSvrNew7221Fetcher.GetDataValue(5, 0); // 코스피외국인순매수
                curRow[5] = m_CpSvrNew7221Fetcher.GetDataValue(8, 0); // 코스피기관계순매수
                curRow[6] = m_CpSvrNew7221Fetcher.GetDataValue(17, 0); // 코스피투신순매수
                curRow[7] = m_CpSvrNew7221Fetcher.GetDataValue(26, 0); // 코스피기금순매수
                curRow[8] = m_CpSvrNew7221Fetcher.GetDataValue(29, 0); // 코스피국가순매수
                curRow[9] = m_CpSvrNew7221Fetcher.GetDataValue(2, 2); // 선물 개인 순매수
                curRow[10] = m_CpSvrNew7221Fetcher.GetDataValue(5, 2); // 선물 외국인 순매수
                curRow[11] = m_CpSvrNew7221Fetcher.GetDataValue(8, 2); // 선물 기관계 순매수
                curRow[12] = m_CpSvrNew7221Fetcher.GetDataValue(2, 3); // 개인옵션콜 순매수
                curRow[13] = m_CpSvrNew7221Fetcher.GetDataValue(5, 3); // 외국인옵션콜 순매수
                curRow[14] = m_CpSvrNew7221Fetcher.GetDataValue(8, 3); // 기관계옵션콜 순매수
                curRow[15] = m_CpSvrNew7221Fetcher.GetDataValue(2, 4); // 개인옵션풋 순매수
                curRow[16] = m_CpSvrNew7221Fetcher.GetDataValue(5, 4); // 외국인옵션풋 순매수
                curRow[17] = m_CpSvrNew7221Fetcher.GetDataValue(8, 4); // 기관계옵션풋 순매수
                curRow[0] = curRowIndex; // BarIndex
                curRow[1] = curRowIndex; // DayIndex

                GlobalVar.CPSvrNew7221DataDownloaded = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            m_CpSvrNew7221TryCount++;
        }

        public void OnReceived_StockChart()
        {
            m_Lock = false;

            StockChartTable curTable = m_EasyTraderDataSet.GetStockChartTable();
            if (curTable == null)
                return;
            // 수신 개수
            object dataCount = m_StockChartFetcher.GetHeaderValue(3);
            if (Convert.ToInt32(dataCount) == 0)
            {
                m_StockChartTryCount++;
                return;
            }
            int curRowCount = curTable.Rows.Count;
            // 현재 테이블의 행개수가 현재 인덱스+1 보다 작으면 모자른 행만큼 더 추가해야 한다.
            // 장 중간에 시작했을 때에 라도 행개수가 부족함이 없이 하기 위해서이다.
            // 0번행은 시초가가 들어가도록 한다.
            if (curRowCount < Convert.ToInt32(dataCount) + 1)
            {
                int addCount = Convert.ToInt32(dataCount) - curRowCount + 1;
                // 필요한 개수만큼 추가해 준다.
                for (int i = 0; i < addCount; i++)
                {
                    // GlobalVar.FutOptChartTableColSize
                    if (curTable.GetRowCount() == GlobalVar.MaxDayIndex + 1)
                        break;

                    object[] StockChartBuffer = new object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    curTable.AddRow(StockChartBuffer);
                }
            }

            DataRow curRow = curTable.Rows[0];

            curRow[2] = m_StockChartFetcher.GetDataValue(0, Convert.ToInt32(dataCount) - 1); // 날짜
            curRow[3] = m_StockChartFetcher.GetDataValue(1, Convert.ToInt32(dataCount) - 1); // 시간
            curRow[4] = m_StockChartFetcher.GetDataValue(2, Convert.ToInt32(dataCount) - 1); // 시가
            curRow[5] = m_StockChartFetcher.GetDataValue(2, Convert.ToInt32(dataCount) - 1); // 고가
            curRow[6] = m_StockChartFetcher.GetDataValue(2, Convert.ToInt32(dataCount) - 1); // 저가
            curRow[7] = m_StockChartFetcher.GetDataValue(2, Convert.ToInt32(dataCount) - 1); // 종가
            curRow[8] = m_StockChartFetcher.GetDataValue(7, Convert.ToInt32(dataCount) - 1); // 거래량
            curRow[0] = 0; // BarIndex
            curRow[1] = 0; // DayIndex
            // 데이터를 가져오지 못하면 아무일도 하지 않는다.
            if (Convert.ToInt32(dataCount) != 0)
            {
                for (int i = Convert.ToInt32(dataCount) - 1, j = 1; i > -1; i--, j++)
                {
                    curRow = curTable.Rows[j];

                    curRow[2] = m_StockChartFetcher.GetDataValue(0, i); // 날짜
                    curRow[3] = m_StockChartFetcher.GetDataValue(1, i); // 시간
                    curRow[4] = m_StockChartFetcher.GetDataValue(2, i); // 시가
                    curRow[5] = m_StockChartFetcher.GetDataValue(3, i); // 고가
                    curRow[6] = m_StockChartFetcher.GetDataValue(4, i); // 저가
                    curRow[7] = m_StockChartFetcher.GetDataValue(5, i); // 종가
                    curRow[8] = m_StockChartFetcher.GetDataValue(7, i); // 거래량
                    int dayIndex = GlobalVar.DayIndex();
                    curRow[0] = j; // BarIndex
                    curRow[1] = dayIndex; // DayIndex
                }
                GlobalVar.StockChartDataDownloaded = true;
            }

            m_StockChartTryCount++;
        }

        public void OnReceived_CmeMst()
        {
            m_Lock = false;

            CmeMstTable curTable = m_EasyTraderDataSet.GetCmeMstTable();
            if (curTable == null)
                return;
            object curTime = m_CmeMstFetcher.GetHeaderValue(28); // 시각
            int curRowCount = curTable.Rows.Count;
            int curRowIndex = GlobalVar.NightIndex(curTime.ToString());
            // 현재 테이블의 행개수가 현재 인덱스+1 보다 작으면 모자른 행만큼 더 추가해야 한다.
            // 장 중간에 시작했을 때에 라도 행개수가 부족함이 없이 하기 위해서이다.
            // 0번행은 시초가가 들어가도록 한다.
            if (curRowCount < curRowIndex + 1)
            {
                int addCount = (curRowIndex + 1) - curRowCount;
                // 필요한 개수만큼 추가해 준다.
                for (int i = 0; i < addCount; i++)
                {
                    // GlobalVar.CmeMstTableColSize
                    object[] CmeMstBuffer = new object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    curTable.AddRow(CmeMstBuffer);
                }
            }

            DataRow curRow = curTable.Rows[curRowIndex];
            try
            {
                curRow[2] = m_CmeMstFetcher.GetHeaderValue(28); // 시각
                curRow[3] = m_CmeMstFetcher.GetHeaderValue(18); // 현재가
                curRow[4] = m_CmeMstFetcher.GetHeaderValue(19); // 시가
                curRow[5] = m_CmeMstFetcher.GetHeaderValue(20); // 고가
                curRow[6] = m_CmeMstFetcher.GetHeaderValue(21); // 저가
                curRow[7] = m_CmeMstFetcher.GetHeaderValue(46); // 매수총호가수량
                curRow[8] = m_CmeMstFetcher.GetHeaderValue(57); // 매도총호가수량
                curRow[9] = m_CmeMstFetcher.GetHeaderValue(68); // 매수총호가건수
                curRow[10] = m_CmeMstFetcher.GetHeaderValue(74); // 매도총호가건수
                curTime = Convert.ToString(m_CmeMstFetcher.GetHeaderValue(0));
                curRow[0] = curRowIndex; // BarIndex
                curRow[1] = curRowIndex; // NightIndex
                GlobalVar.CmeMstDataDownloaded = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            m_CmeMstTryCount++;
        }

#endregion
#region Get RealTime Data
        public void PutCmeCurrData()
        {
            if (CmeCurrIndex < 0)
                return;
            m_CmeCurrDataLock = true;
            CmeCurrTable a_CmeCurrTable = m_EasyTraderDataSet.GetCmeCurrTable();
            int curRowCount = a_CmeCurrTable.GetRowCount();
            // 현재 테이블의 행개수가 현재 인덱스+1 보다 작으면 모자른 행만큼 더 추가해야 한다.
            // 장 중간에 시작했을 때에 라도 행개수가 부족함이 없이 하기 위해서이다.
            // 0번행은 시초가가 들어가도록 한다.
            if (curRowCount < CmeCurrIndex + 1)
            {
                int addCount = CmeCurrIndex + 1 - curRowCount;
                // 필요한 개수만큼 추가해 준다.
                for (int i = 0; i < addCount; i++)
                {
                    // GlobalVar.CmeCurrTableColSize
                    object[] CmeCurrBuffer = new object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    a_CmeCurrTable.AddRow(CmeCurrBuffer);
                }
            }
            DataRow curRow = a_CmeCurrTable.Rows[CmeCurrIndex];
            curRow[2] = CmeCurrTableBuffer[2]; // 체결시각
            curRow[3] = CmeCurrTableBuffer[3]; // 종목코드
            curRow[4] = CmeCurrTableBuffer[4]; // 현재가
            curRow[5] = CmeCurrTableBuffer[5]; // 베이시스
            curRow[6] = CmeCurrTableBuffer[6]; // 시가
            curRow[7] = CmeCurrTableBuffer[7]; // 고가
            curRow[8] = CmeCurrTableBuffer[8]; // 저가
            curRow[9] = CmeCurrTableBuffer[9]; // 누적체결수량
            curRow[10] = CmeCurrTableBuffer[10]; // 미결제약정
            curRow[0] = CmeCurrIndex; // BarIndex
            curRow[1] = CmeCurrIndex; // DayIndex

            m_CmeCurrDataLock = true;
        }

        // 버퍼에서 테이블로 옮겨 놓는 작업을 한다.
        public void PutCPSvr8111SData()
        {

            if (CpSvr8111SIndex < 0)
                return;
            m_CPSvr8111SDataLock = true;
            CPSvr8111STable a_CPSvr8111STable = m_EasyTraderDataSet.GetCPSvr8111STable();
            int curRowCount = a_CPSvr8111STable.GetRowCount();
            // 현재 테이블의 행개수가 현재 인덱스+1 보다 작으면 모자른 행만큼 더 추가해야 한다.
            // 장 중간에 시작했을 때에 라도 행개수가 부족함이 없이 하기 위해서이다.
            // 0번행은 시초가가 들어가도록 한다.
            if (curRowCount < CpSvr8111SIndex + 1)
            {
                int addCount = (CpSvr8111SIndex + 1) - curRowCount;
                // 필요한 개수만큼 추가해 준다.
                for (int i = 0; i < addCount; i++)
                {
                    // GlobalVar.CPSvr8111STableColSize
                    object[] CPSvr8111SBuffer = new object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    a_CPSvr8111STable.AddRow(CPSvr8111SBuffer);
                }
            }
            DataRow curRow = null;
            object curTime = CPSvr8111STableBuffer[2]; // 시각
            int intTime = Convert.ToInt32(curTime);
            int openTime = GlobalVar.TimeToInt(GlobalVar.DayOpenTime, 0);
            curRowCount = a_CPSvr8111STable.GetRowCount();
            
            // 시간이 바뀔때 현재 정보를 맨 처음에 넣어 준다.
            if (intTime >= openTime && curRowCount >= 1 && CPSvr8111SOpenSet == false)
            {
                curRow = a_CPSvr8111STable.Rows[0];
                curRow[2] = CPSvr8111STableBuffer[2]; // 시각
                curRow[3] = CPSvr8111STableBuffer[3]; // 차익 매수
                curRow[4] = CPSvr8111STableBuffer[4]; // 차익 매도
                curRow[5] = CPSvr8111STableBuffer[5]; // 비차익 매수
                curRow[6] = CPSvr8111STableBuffer[6]; // 비차익 매도
                curRow[7] = CPSvr8111STableBuffer[7]; // 차익 순매수
                curRow[8] = CPSvr8111STableBuffer[8]; // 비차익 순매수
                curRow[9] = CPSvr8111STableBuffer[9]; // 전체순매수
                curRow[0] = 0;
                curRow[1] = 0;
                CPSvr8111SOpenSet = true;
            }

            if (CpSvr8111SIndex > curRowCount - 1)
                return;
            curRow = a_CPSvr8111STable.Rows[CpSvr8111SIndex];
            curRow[2] = CPSvr8111STableBuffer[2]; // 시각
            curRow[3] = CPSvr8111STableBuffer[3]; // 차익 매수
            curRow[4] = CPSvr8111STableBuffer[4]; // 차익 매도
            curRow[5] = CPSvr8111STableBuffer[5]; // 비차익 매수
            curRow[6] = CPSvr8111STableBuffer[6]; // 비차익 매도
            curRow[7] = CPSvr8111STableBuffer[7]; // 차익 순매수
            curRow[8] = CPSvr8111STableBuffer[8]; // 비차익 순매수
            curRow[9] = CPSvr8111STableBuffer[9]; // 전체순매수
            curRow[0] = CpSvr8111SIndex; // BarIndex
            curRow[1] = CpSvr8111SIndex; // DayIndex

            m_CPSvr8111SDataLock = false;
        }

        public void PutFutureCurOnlyData()
        {
            if (FutureCurOnlyIndex < 0)
                return;
            m_FutureCurOnlyLock = true;
            FutureCurOnlyTable a_FutureCurOnlyTable = m_EasyTraderDataSet.GetFutureCurOnlyTable();
            int curRowCount = a_FutureCurOnlyTable.GetRowCount();
            // 현재 테이블의 행개수가 현재 인덱스+1 보다 작으면 모자른 행만큼 더 추가해야 한다.
            // 장 중간에 시작했을 때에 라도 행개수가 부족함이 없이 하기 위해서이다.
            // 0번행은 시초가가 들어가도록 한다.
            if (curRowCount < FutureCurOnlyIndex + 1)
            {
                int addCount = FutureCurOnlyIndex + 1 - curRowCount;
                // 필요한 개수만큼 추가해 준다.
                for (int i = 0; i < addCount; i++)
                {
                    // GlobalVar.FutureCurOnlyTableColSize
                    object[] FutureCurOnlyBuffer = new object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    a_FutureCurOnlyTable.AddRow(FutureCurOnlyBuffer);
                }
            }
            DataRow curRow = a_FutureCurOnlyTable.Rows[FutureCurOnlyIndex];
            curRow[2] = FutureCurOnlyTableBuffer[2]; // 시각
            curRow[3] = FutureCurOnlyTableBuffer[3]; // 종목코드
            curRow[4] = FutureCurOnlyTableBuffer[4]; // 현재가
            curRow[5] = FutureCurOnlyTableBuffer[5]; // 베이시스
            curRow[6] = FutureCurOnlyTableBuffer[6]; // 시가
            curRow[7] = FutureCurOnlyTableBuffer[7]; // 고가
            curRow[8] = FutureCurOnlyTableBuffer[8]; // 저가
            curRow[9] = FutureCurOnlyTableBuffer[9]; // 최고가
            curRow[10] = FutureCurOnlyTableBuffer[10]; // 최저가
            curRow[11] = FutureCurOnlyTableBuffer[11]; // 미결제약정
            curRow[0] = FutureCurOnlyIndex; // BarIndex
            curRow[1] = FutureCurOnlyIndex; // DayIndex

            m_FutureCurOnlyLock = false;
        }

        public void PutFutureJpBidData()
        {
            if (FutureJpBidIndex < 0)
                return;
            m_FutureJpBidLock = true;
            FutureJpBidTable a_FutureJpBidTable = m_EasyTraderDataSet.GetFutureJpBidTable();
            int curRowCount = a_FutureJpBidTable.GetRowCount();
            // 현재 테이블의 행개수가 현재 인덱스+1 보다 작으면 모자른 행만큼 더 추가해야 한다.
            // 장 중간에 시작했을 때에 라도 행개수가 부족함이 없이 하기 위해서이다.
            // 0번행은 시초가가 들어가도록 한다.
            if (curRowCount < FutureJpBidIndex + 1)
            {
                int addCount = FutureJpBidIndex + 1 - curRowCount;
                // 필요한 개수만큼 추가해 준다.
                for (int i = 0; i < addCount; i++)
                {
                    // GlobalVar.FutureJpBidTableColSize
                    object[] FutureJpBidBuffer = new object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    a_FutureJpBidTable.AddRow(FutureJpBidBuffer);
                }
            }
            DataRow curRow = a_FutureJpBidTable.Rows[FutureJpBidIndex];
            curRow[2] = FutureJpBidTableBuffer[2]; // 처리시각
            curRow[3] = FutureJpBidTableBuffer[3]; // 선물코드
            curRow[4] = FutureJpBidTableBuffer[4]; // 매도총호가잔량 
            curRow[5] = FutureJpBidTableBuffer[5]; // 매수총호가잔량
            curRow[6] = FutureJpBidTableBuffer[6]; // 매도총호가잔량 
            curRow[7] = FutureJpBidTableBuffer[7]; // 매수총호가잔량
            curRow[8] = FutureJpBidTableBuffer[8]; // 매도총호가잔량 
            curRow[9] = FutureJpBidTableBuffer[9]; // 매수총호가잔량
            curRow[10] = FutureJpBidTableBuffer[10]; // 매도총호가잔량 
            curRow[11] = FutureJpBidTableBuffer[11]; // 매수총호가잔량
            curRow[12] = FutureJpBidTableBuffer[12]; // 매도총호가잔량 
            curRow[13] = FutureJpBidTableBuffer[13]; // 매수총호가잔량
            curRow[14] = FutureJpBidTableBuffer[14]; // 매도총호가잔량 
            curRow[15] = FutureJpBidTableBuffer[15]; // 매수총호가잔량
            curRow[16] = FutureJpBidTableBuffer[16]; // 매도총호가잔량 
            curRow[17] = FutureJpBidTableBuffer[17]; // 매수총호가잔량
            curRow[18] = FutureJpBidTableBuffer[18]; // 매도총호가잔량 
            curRow[19] = FutureJpBidTableBuffer[19]; // 매수총호가잔량
            curRow[20] = FutureJpBidTableBuffer[20]; // 매도총호가잔량 
            curRow[21] = FutureJpBidTableBuffer[21]; // 매수총호가잔량
            curRow[22] = FutureJpBidTableBuffer[22]; // 매도총호가잔량 
            curRow[23] = FutureJpBidTableBuffer[23]; // 매수총호가잔량
            curRow[24] = FutureJpBidTableBuffer[24]; // 매도총호가잔량 
            curRow[25] = FutureJpBidTableBuffer[25]; // 매수총호가잔량
            curRow[26] = FutureJpBidTableBuffer[26]; // 매도총호가잔량 
            curRow[27] = FutureJpBidTableBuffer[27]; // 매수총호가잔량
            curRow[28] = FutureJpBidTableBuffer[28]; // 매도총호가잔량 
            curRow[29] = FutureJpBidTableBuffer[29]; // 매수총호가잔량
            curRow[30] = FutureJpBidTableBuffer[30]; // 매도총호가잔량 
            curRow[31] = FutureJpBidTableBuffer[31]; // 매수총호가잔량
            curRow[32] = FutureJpBidTableBuffer[32]; // 매도총호가잔량 
            curRow[33] = FutureJpBidTableBuffer[33]; // 매수총호가잔량
            curRow[34] = FutureJpBidTableBuffer[34]; // 매도총호가잔량 
            curRow[35] = FutureJpBidTableBuffer[35]; // 매수총호가잔량
            curRow[36] = FutureJpBidTableBuffer[36]; // 매도총호가잔량 
            curRow[37] = FutureJpBidTableBuffer[37]; // 매수총호가잔량
            curRow[38] = FutureJpBidTableBuffer[38]; // 매도총호가잔량 
            curRow[0] = FutureJpBidIndex; // BarIndex
            curRow[1] = FutureJpBidIndex; // DayIndex

            GlobalVar.FutureJpBidDatadownloaded = true;

            m_FutureJpBidLock = false;
        }

#endregion
#region  Real Time OnReceived Handlers
     
        // 실시간 선물 호가 수집 객체 핸들러
        public void OnReceived_FutureJpBid()
        {
            if (m_FutureJpBidLock == true)
                return;

            FutureJpBidTableBuffer[0] = 0; // BarIndex
            FutureJpBidTableBuffer[1] = 0; // DayIndex
            FutureJpBidTableBuffer[2] = m_FutureJpBid.GetHeaderValue(1); // 처리시각
            FutureJpBidTableBuffer[3] = m_FutureJpBid.GetHeaderValue(0); // 선물코드
            FutureJpBidTableBuffer[4] = m_FutureJpBid.GetHeaderValue(2); // 매도총호가잔량 
            FutureJpBidTableBuffer[5] = m_FutureJpBid.GetHeaderValue(3); // 매수총호가잔량
            FutureJpBidTableBuffer[6] = m_FutureJpBid.GetHeaderValue(4); // 매도총호가잔량 
            FutureJpBidTableBuffer[7] = m_FutureJpBid.GetHeaderValue(5); // 매수총호가잔량
            FutureJpBidTableBuffer[8] = m_FutureJpBid.GetHeaderValue(6); // 매도총호가잔량 
            FutureJpBidTableBuffer[9] = m_FutureJpBid.GetHeaderValue(7); // 매수총호가잔량
            FutureJpBidTableBuffer[10] = m_FutureJpBid.GetHeaderValue(8); // 매도총호가잔량 
            FutureJpBidTableBuffer[11] = m_FutureJpBid.GetHeaderValue(9); // 매수총호가잔량
            FutureJpBidTableBuffer[12] = m_FutureJpBid.GetHeaderValue(10); // 매도총호가잔량 
            FutureJpBidTableBuffer[13] = m_FutureJpBid.GetHeaderValue(11); // 매수총호가잔량
            FutureJpBidTableBuffer[14] = m_FutureJpBid.GetHeaderValue(12); // 매도총호가잔량 
            FutureJpBidTableBuffer[15] = m_FutureJpBid.GetHeaderValue(13); // 매수총호가잔량
            FutureJpBidTableBuffer[16] = m_FutureJpBid.GetHeaderValue(14); // 매도총호가잔량 
            FutureJpBidTableBuffer[17] = m_FutureJpBid.GetHeaderValue(15); // 매수총호가잔량
            FutureJpBidTableBuffer[18] = m_FutureJpBid.GetHeaderValue(16); // 매도총호가잔량 
            FutureJpBidTableBuffer[19] = m_FutureJpBid.GetHeaderValue(17); // 매수총호가잔량
            FutureJpBidTableBuffer[20] = m_FutureJpBid.GetHeaderValue(18); // 매도총호가잔량 
            FutureJpBidTableBuffer[21] = m_FutureJpBid.GetHeaderValue(19); // 매수총호가잔량
            FutureJpBidTableBuffer[22] = m_FutureJpBid.GetHeaderValue(20); // 매도총호가잔량 
            FutureJpBidTableBuffer[23] = m_FutureJpBid.GetHeaderValue(21); // 매수총호가잔량
            FutureJpBidTableBuffer[24] = m_FutureJpBid.GetHeaderValue(22); // 매도총호가잔량 
            FutureJpBidTableBuffer[25] = m_FutureJpBid.GetHeaderValue(23); // 매수총호가잔량
            FutureJpBidTableBuffer[26] = m_FutureJpBid.GetHeaderValue(24); // 매도총호가잔량 
            FutureJpBidTableBuffer[27] = m_FutureJpBid.GetHeaderValue(25); // 매수총호가잔량
            FutureJpBidTableBuffer[28] = m_FutureJpBid.GetHeaderValue(26); // 매도총호가잔량 
            FutureJpBidTableBuffer[29] = m_FutureJpBid.GetHeaderValue(27); // 매수총호가잔량
            FutureJpBidTableBuffer[30] = m_FutureJpBid.GetHeaderValue(28); // 매도총호가잔량 
            FutureJpBidTableBuffer[31] = m_FutureJpBid.GetHeaderValue(29); // 매수총호가잔량
            FutureJpBidTableBuffer[32] = m_FutureJpBid.GetHeaderValue(30); // 매도총호가잔량 
            FutureJpBidTableBuffer[33] = m_FutureJpBid.GetHeaderValue(31); // 매수총호가잔량
            FutureJpBidTableBuffer[34] = m_FutureJpBid.GetHeaderValue(32); // 매도총호가잔량 
            FutureJpBidTableBuffer[35] = m_FutureJpBid.GetHeaderValue(33); // 매수총호가잔량
            FutureJpBidTableBuffer[36] = m_FutureJpBid.GetHeaderValue(34); // 매도총호가잔량 
            FutureJpBidTableBuffer[37] = m_FutureJpBid.GetHeaderValue(35); // 매수총호가잔량
            FutureJpBidTableBuffer[38] = m_FutureJpBid.GetHeaderValue(36); // 매도총호가잔량 

            object curTime = m_FutureJpBid.GetHeaderValue(1); // 처리시각
            FutureJpBidIndex = GlobalVar.DayIndex(curTime.ToString());
        }

        // 실시간 선물 지수 수집 객체 핸들러
        public void OnReceived_FutureCurOnly()
        {
            if (m_FutureCurOnlyLock == true)
                return;

            FutureCurOnlyTableBuffer[0] = 0; // BarIndex
            FutureCurOnlyTableBuffer[1] = 0; // DayIndex
            FutureCurOnlyTableBuffer[2] = m_FutureCurOnly.GetHeaderValue(15); // 시각
            FutureCurOnlyTableBuffer[3] = m_FutureCurOnly.GetHeaderValue(0); // 종목코드
            FutureCurOnlyTableBuffer[4] = m_FutureCurOnly.GetHeaderValue(1); // 현재가
            FutureCurOnlyTableBuffer[5] = m_FutureCurOnly.GetHeaderValue(5); // 베이시스
            FutureCurOnlyTableBuffer[6] = m_FutureCurOnly.GetHeaderValue(7); // 시가
            FutureCurOnlyTableBuffer[7] = m_FutureCurOnly.GetHeaderValue(8); // 고가
            FutureCurOnlyTableBuffer[8] = m_FutureCurOnly.GetHeaderValue(9); // 저가
            FutureCurOnlyTableBuffer[9] = m_FutureCurOnly.GetHeaderValue(10); // 최고가
            FutureCurOnlyTableBuffer[10] = m_FutureCurOnly.GetHeaderValue(11); // 최저가
            FutureCurOnlyTableBuffer[11] = m_FutureCurOnly.GetHeaderValue(14); // 미결제약정

            object curTime = m_FutureCurOnly.GetHeaderValue(15); // 시각
            FutureCurOnlyIndex = GlobalVar.DayIndexWithSec(curTime.ToString());
            // 이것으로 서버 시간을 확인한다.
            m_ServerSec = GlobalVar.GetServerSec(curTime.ToString());
            // 여기서 현재가를 항상 갱신해 준다.
            GlobalVar.CurClose = Convert.ToDouble(m_FutureCurOnly.GetHeaderValue(1));


        }

        // 실시간 프로그램 거래량 수집 객체
        public void OnReceived_CpSvr8111S()
        {
            if (m_CPSvr8111SDataLock == true)
                return;

            CPSvr8111STableBuffer[0] = 0; // BarIndex
            CPSvr8111STableBuffer[1] = 0; // DayIndex
            CPSvr8111STableBuffer[2] = m_CpSvr8111S.GetHeaderValue(1); // 시각
            CPSvr8111STableBuffer[3] = m_CpSvr8111S.GetHeaderValue(13); // 차익 매수
            CPSvr8111STableBuffer[4] = m_CpSvr8111S.GetHeaderValue(7); // 차익 매도
            CPSvr8111STableBuffer[5] = m_CpSvr8111S.GetHeaderValue(31); // 비차익 매수
            CPSvr8111STableBuffer[6] = m_CpSvr8111S.GetHeaderValue(25); // 비차익 매도
            double profitBuy = 0;
            double profitSell = 0;
            double nonArbitrageBuy = 0;
            double nonArbitrageSell = 0;
            double profitPureBuy = 0;
            double nonArbitragePureBuy = 0;
            double totalPureBuy = 0;

            profitBuy = Convert.ToDouble(CPSvr8111STableBuffer[3]);
            profitSell = Convert.ToDouble(CPSvr8111STableBuffer[4]);
            nonArbitrageBuy = Convert.ToDouble(CPSvr8111STableBuffer[5]);
            nonArbitrageSell = Convert.ToDouble(CPSvr8111STableBuffer[6]);
            profitPureBuy = profitBuy - profitSell;
            nonArbitragePureBuy = nonArbitrageBuy - nonArbitrageSell;
            totalPureBuy = profitPureBuy + nonArbitragePureBuy;

            CPSvr8111STableBuffer[7] = profitPureBuy;
            CPSvr8111STableBuffer[8] = nonArbitragePureBuy;
            CPSvr8111STableBuffer[9] = totalPureBuy;

            object curTime = m_CpSvr8111S.GetHeaderValue(1); // 시각
            CpSvr8111SIndex = GlobalVar.DayIndex(curTime.ToString());
        }

        // 실시간 야간 선물 수집 객체 핸들러
        public void OnReceived_CmeCurr()
        {
            if (m_CmeCurrDataLock == true)
                return;

            CmeCurrTableBuffer[0] = 0; // BarIndex
            CmeCurrTableBuffer[1] = 1; // DayIndex
            CmeCurrTableBuffer[2] = m_CmeCur.GetHeaderValue(12); // 체결시각
            CmeCurrTableBuffer[3] = m_CmeCur.GetHeaderValue(0); // 종목코드
            CmeCurrTableBuffer[4] = m_CmeCur.GetHeaderValue(1); // 현재가
            CmeCurrTableBuffer[5] = m_CmeCur.GetHeaderValue(3); // 베이시스
            CmeCurrTableBuffer[6] = m_CmeCur.GetHeaderValue(5); // 시가
            CmeCurrTableBuffer[7] = m_CmeCur.GetHeaderValue(6); // 고가
            CmeCurrTableBuffer[8] = m_CmeCur.GetHeaderValue(7); // 저가
            CmeCurrTableBuffer[9] = m_CmeCur.GetHeaderValue(9); // 누적체결수량
            CmeCurrTableBuffer[10] = m_CmeCur.GetHeaderValue(11); // 미결제약정

            object curTime = m_CmeCur.GetHeaderValue(12); // 체결시각
            CmeCurrIndex = GlobalVar.NightIndex(curTime.ToString());
        }
#endregion
    }
}
